100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > python爬虫经典段子_Python爬虫-爬取糗事百科段子

python爬虫经典段子_Python爬虫-爬取糗事百科段子

时间:2020-04-08 00:49:14

相关推荐

python爬虫经典段子_Python爬虫-爬取糗事百科段子

闲来无事,学学python爬虫。

在正式学爬虫前,简单学习了下HTML和CSS,了解了网页的基本结构后,更加快速入门。

1.获取糗事百科url

2.先抓取HTML页面

importurllibimporturllib2importre

page= 2url= '/hot/page/' +str(page) #对应第2页的urlrequest= urllib2.Request(url) #发出申请

response= urllib2.urlopen(request) #收到回应

当然这里可能会产生error:主要有HTTPError和URLError。

产生URLError的原因可能是:

网络无连接,即本机无法上网

连接不到特定的服务器

服务器不存在

异常捕获解决办法:

importurllib2

requset= urllib2.Request('')try:

urllib2.urlopen(request)excepturllib2.URLError, e:printe.reason

HTTPError是URLError的子类,利用urlopen方法发出一个请求时,服务器上都会对应一个应答对象response,其中它包含一个数字”状态码”。举个例子,假如response是一个”重定向”,需定位到别的地址获取文档,urllib2将对此进行处理。常见的状态码:

200:请求成功 处理方式:获得响应的内容,进行处理

202:请求被接受,但处理尚未完成 处理方式:阻塞等待

204:服务器端已经实现了请求,但是没有返回新的信 息。如果客户是用户代理,则无须为此更新自身的文档视图。 处理方式:丢弃

404:没有找到 处理方式:丢弃

500:服务器内部错误 服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器端的源代码出现错误时出现。

异常捕获解决办法:

importurllib2

req= urllib2.Request('/cqcre')try:

urllib2.urlopen(req)excepturllib2.HTTPError, e:printe.codeprint e.reason

注:HTTPError是URLError的子类,在产生URLError时也会触发产生HTTPError。因此应该先处理HTTPError。上述代码可改写为:

importurllib2

req= urllib2.Request('/cqcre')try:

urllib2.urlopen(req)excepturllib2.HTTPError, e:printe.codeexcepturllib2.URLError, e:printe.reasonelse:print "OK"

如果无法获得回应,可能需要加入header模拟浏览器发出请求:

importurllibimporturllib2

page= 1url= '/hot/page/' +str(page)

user_agent= 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'headers= { 'User-Agent': user_agent }try:

request= urllib2.Request(url,headers =headers) # 加入header

response=urllib2.urlopen(request)printresponse.read()excepturllib2.URLError, e:if hasattr(e,"code"):printe.codeif hasattr(e,"reason"):print e.reason

3.分析页面获取段子

如上图所示,划红对勾的是不同的段子,每个段子都由

...包裹起来。我们点开其中一个,获取其中的用户名、段子内容和点赞数这三个信息。这三个信息分别用红、蓝、黑下划线圈起来。解析过程主要由正则表达式实现。

解析用户名。正则表达式为:

.*?

(.*?)

上图中用户名称为旖旎萌萌,处于

中间,用(.*?)代之。

解析段子内容。正则表达式为:

(.*?) 同理,文字部分在和之间。之间的所有符号(含换行符)用.*?解决。

解析点赞数。正则表达式为:

.*?"number">(.*?) 同理。用(.*?)代替1520。

正则表达式解释:(参考崔庆才博客)

1).*? 是一个固定的搭配,.和*代表可以匹配任意无限多个字符,加上?表示使用非贪婪模式进行匹配,也就是我们会尽可能短地做匹配,以后我们还会大量用到 .*? 的搭配。

2)(.*?)代表一个分组,在这个正则表达式中我们匹配了五个分组,在后面的遍历item中,item[0]就代表第一个(.*?)所指代的内容,item[1]就代表第二个(.*?)所指代的内容,以此类推。

3)re.S 标志代表在匹配时为点任意匹配模式,点 . 也可以代表换行符。

content = response.read().decode('utf-8')

pattern= pile('

.*?

(.*?)

.*?(.*?).*?.*?"number">(.*?)',re.S)

items= re.findall(pattern,content) # 参考python中的re模块,作用是在content中寻找可以匹配pattern的串,即段子

但是有个问题,上面的表达式将有图和无图的段子都爬取下来了,但是在图片一般不会显示,所以需要去掉有图的段子,只爬取无图片的段子。需要稍微改动正则表达式。

上图是无图的段子html代码,下图是有图的段子的html代码:

红线划的

包含了图片部分,而这条语句在无图段子的html中是不存在的,所以利用这条语句中的“img”(上图下划线)来过滤段子。同时注意到这条语句处在段子内容和点赞数中间。

所以在段子内容和点赞这两个正则语句之间加上一个(.*?)即可,这样一来,只要检测到包括“img”,就过滤掉。

content = response.read().decode('utf-8')

pattern= pile('

.*?

(.*?)

.*?(.*?)(.*?).*?"number">(.*?)' # 注意这个(.*?),re.S)

items=re.findall(pattern,content) # items就是根据正则表达式筛选到的字符串(html串)for item initems:

haveImg= re.search("img", item[2]) # 0,1,2,3分别表示用户名,段子内容,图片,点赞数。所以用item[2]来检测过滤if nothaveImg:print item[0], item[1], item[3]

好,以上代码就是可以实现将一页中的无图段子全部爬取出来:代码:

importurllibimporturllib2importre

page= 2url= '/hot/page/' +str(page)

user_agent= 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'headers= {'User-Agent':user_agent}

request= urllib2.Request(url, headers=headers)

response=urllib2.urlopen(request)

content= response.read().decode('utf-8')

pattern= pile('

.*?

(.*?)

.*?(.*?)(.*?).*?"number">(.*?)',re.S)

items=re.findall(pattern,content)for item initems:

haveImg= re.search("img", item[2])if nothaveImg:print item[0], item[1], item[3]

4.以上代码是核心,但是略有简陋,稍加修补:

#coding:utf-8

importurllibimporturllib2importreclassSpider_QSBK:def __init__(self):

self.page_index= 2self.enable=False

self.stories=[]

self.user_agent= 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'self.headers= {'User-Agent':self.user_agent}defgetPage(self, page_index):

url= '/hot/page/' +str(page_index)try:

request= urllib2.Request(url, headers=self.headers)

response=urllib2.urlopen(request)

content= response.read().decode('utf-8')returncontentexcepturllib2.URLError, e:printe.reasonreturnNonedefgetStories(self,page_index):

content=self.getPage(page_index)

pattern= pile('

.*?

(.*?)

.*?(.*?)(.*?).*?"number">(.*?)',re.S)

items=re.findall(pattern,content)for item initems:

haveImg= re.search("img", item[2])if nothaveImg:

self.stories.append([item[0], item[1], item[3]])returnself.storiesdefShowStories(self, page_index):

self.getStories(page_index)for st inself.stories:print u"第%d页\t发布人:%s\t点赞数:%s\n%s" %(page_index, st[0], st[2], st[1])delself.storiesdefstart(self):

self.enable=True#while self.enable:

self.ShowStories(self.page_index)

self.page_index+= 1spider=Spider_QSBK()

spider.start()

结果一样:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。