1、Python爬虫实战Python爬虫实战Python爬虫实战1:爬取糗事百科段子大家好,前面入门已经说了那么多根底知识了,下面我们做几个实战项目来挑战一下吧。那么这次为大家带来,Python爬取糗事百科的小段子的例子。首先,糗事百科大家都听说过吧?糗友们发的搞笑的段子一抓一大把,这次我们尝试一下用爬虫把他们抓取下来。本篇目标3.实现每按一次回车显示一个段子的发布时间,发布人,段子内容,点赞数。糗事百科是不需要登录的,所以也没必要用到Cookie,另外糗事百科有的段子是附图的,我们把图抓下来图片不便于显示,那么我们就尝试过滤掉有图的段子吧。好,现在我们尝试抓取一下糗事百科的热门段子吧,每按下一次
2、回车我们显示一个段子。首先我们确定好页面的URL是 .qiushibaike./hot/page/1,其中最后一个数字1代表页数,我们可以传入不同的值来获得某一页的段子内容。我们初步构建如下的代码来打印页面代码内容试试看,先构造最根本的页面抓取方式,看看会不会成功12345678910111213141516# -*- coding:utf-8 -*-importurllibimporturllib2page =1url =.qiushibaike./hot/page/+str(page)try:request =urllib2.Request(url)response =urllib2.ur
3、lopen(request)printresponse.read()excepturllib2.URLError, e:ifhasattr(e,code):ifhasattr(e,reason):运行程序,哦不,它竟然报错了,真是时运不济,命途多舛啊123line 373, in_read_statusraiseBadStatusLine(line)lib.BadStatusLine: 好吧,应该是headers验证的问题,我们加上一个headers验证试试看吧,将代码修改如下1234567891011121314151617# -*- coding:utf-8 -*-importurllib
4、importurllib2page =1url =.qiushibaike./hot/page/+str(page)user_agent =Mozilla/4.0 (patible; MSIE 5.5; Windows NT)headers = User-Agent: user_agent try:request =urllib2.Request(url,headers =headers)response =urllib2.urlopen(request)printresponse.read()excepturllib2.URLError, e:ifhasattr(e,code):ifhasa
5、ttr(e,reason):嘿嘿,这次运行终于正常了,打印出了第一页的HTML代码,大家可以运行下代码试试看。在这里运行结果太长就不贴了。好,获取了HTML代码之后,我们开始分析怎样获取某一页的所有段子。首先我们审查元素看一下,按浏览器的F12,截图如下我们可以看到,每一个段子都是包裹的内容。现在我们想获取发布人,发布日期,段子内容,以与点赞的个数。不过另外注意的是,段子有些是带图片的,如果我们想在控制台显示图片是不现实的,所以我们直接把带有图片的段子给它剔除掉,只保存仅含文本的段子。所以我们参加如下正如此表达式来匹配一下,用到的方法是 re.findall 是找寻所有匹配的内容。方法的用法详
6、情可以看前面说的正如此表达式的介绍。好,我们的正如此表达式匹配语句书写如下,在原来的根底上追加如下代码123456content =response.read().decode(utf-8)pattern =re.pile(.*?a.*?.*?(.*?).*?(.*?)(.*?)(.*?),re.S)items =re.findall(pattern,content)foritem initems:printitem0,item1,item2,item3,item4现在正如此表达式在这里稍作说明1.*? 是一个固定的搭配,.和*代表可以匹配任意无限多个字符,加上?表示使用非贪婪模式进展匹配,也
7、就是我们会尽可能短地做匹配,以后我们还会大量用到 .*? 的搭配。2(.*?)代表一个分组,在这个正如此表达式中我们匹配了五个分组,在后面的遍历item中,item0就代表第一个(.*?)所指代的内容,item1就代表第二个(.*?)所指代的内容,以此类推。3re.S 标志代表在匹配时为点任意匹配模式,点 . 也可以代表换行符。现在我们可以看一下局部运行结果儒雅男神 2015-02-17 14:34:42小时候一个一个拆着放的举个爪7093奇怪的名字啊 2015-02-17 14:49:16回家的路,你追我赶,回家的心情和窗外的阳光一样灿烂。一路向前,离亲人越来越近了。哪里有爸妈哪里才是家,希
8、望所有糗友的爸爸妈妈都身体健康.4803这是其中的两个段子,分别打印了发布人,发布时间,发布内容,附加图片以与点赞数。其中,附加图片的内容我把图片代码整体抠了出来,这个对应item3,所以我们只需要进一步判断item3里面是否含有img这个字样就可以进展过滤了。好,我们再把上述代码中的for循环改为下面的样子1234foritem initems:haveImg =re.search(img,item3)ifnothaveImg:printitem0,item1,item2,item4现在,整体的代码如下12345678910111213141516171819202122232425# -*
9、- coding:utf-8 -*-importurllibimporturllib2importrepage =1url =.qiushibaike./hot/page/+str(page)user_agent =Mozilla/4.0 (patible; MSIE 5.5; Windows NT)headers = User-Agent: user_agent try:request =urllib2.Request(url,headers =headers)response =urllib2.urlopen(request)content =response.read().decode(
10、utf-8)pattern =re.pile(.*?a.*?.*?(.*?).*?(.*?)(.*?)(.*?),re.S)items =re.findall(pattern,content)foritem initems:haveImg =re.search(img,item3)ifnothaveImg:printitem0,item1,item2,item4excepturllib2.URLError, e:ifhasattr(e,code):ifhasattr(e,reason):运行一下看下效果恩,带有图片的段子已经被剔除啦。是不是很开森?3.完善交互,设计面向对象模式好啦,现在最核心
11、的局部我们已经完成啦,剩下的就是修一下边边角角的东西,我们想达到的目的是:按下回车,读取一个段子,显示出段子的发布人,发布日期,内容以与点赞个数。另外我们需要设计面向对象模式,引入类和方法,将代码做一下优化和封装,最后,我们的代码如下所示1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
12、96979899100101102103104105106107108109110_author_ =CQC# -*- coding:utf-8 -*-importurllibimporturllib2importreimportthreadimporttime#糗事百科爬虫类classQSBK:#初始化方法,定义一些变量def_init_(self):self.pageIndex =1self.user_agent =Mozilla/4.0 (patible; MSIE 5.5; Windows NT)#初始化headersself.headers = User-Agent: self.us
13、er_agent #存放段子的变量,每一个元素是每一页的段子们self.stories =#存放程序是否继续运行的变量self.enable =False#传入某一页的索引获得页面代码defgetPage(self,pageIndex):try:url =.qiushibaike./hot/page/+str(pageIndex)#构建请求的requestrequest =urllib2.Request(url,headers =self.headers)#利用urlopen获取页面代码response =urllib2.urlopen(request)#将页面转化为UTF-8编码pageCo
14、de =response.read().decode(utf-8)returnpageCodeexcepturllib2.URLError, e:ifhasattr(e,reason):returnNone#传入某一页代码,返回本页不带图片的段子列表defgetPageItems(self,pageIndex):pageCode =self.getPage(pageIndex)ifnotpageCode:print页面加载失败.returnNonepattern =re.pile(.*?a.*?.*?(.*?).*?(.*?)(.*?)(.*?),re.S)items =re.findall(
15、pattern,pageCode)#用来存储每页的段子们pageStories =#遍历正如此表达式匹配的信息foritem initems:#是否含有图片haveImg =re.search(img,item3)#如果不含有图片,把它参加list中ifnothaveImg:#item0是一个段子的发布者,item1是发布时间,item2是内容,item4是点赞数pageStories.append(item0.strip(),item1.strip(),item2.strip(),item4.strip()returnpageStories#加载并提取页面的内容,参加到列表中defloadP
16、age(self):#如果当前未看的页数少于2页,如此加载新一页ifself.enable =True:iflen(self.stories) 0:#从全局list中获取一页的段子pageStories =self.stories0#当前读到的页数加一nowPage +=1#将全局list中第一个元素删除,因为已经取出delself.stories0#输出该页的段子self.getOneStory(pageStories,nowPage)spider =QSBK()spider.start()好啦,大家来测试一下吧,点一下回车会输出一个段子,包括发布人,发布时间,段子内容以与点赞数,是不是感觉
17、爽爆了!我们第一个爬虫实战项目介绍到这里,欢迎大家继续关注,小伙伴们加油!Python爬虫实战2:XX贴吧帖子大家好,上次我们实验了爬取了糗事百科的段子,那么这次我们来尝试一下爬取XX贴吧的帖子。与上一篇不同的是,这次我们需要用到文件的相关操作。本篇目标首先,我们先观察一下XX贴吧的任意一个帖子。比如:tieba.baidu./p/3138733512?see_lz=1&pn=1,这是一个关于NBA50大的盘点,分析一下这个地址。1234 代表资源传输使用协议tieba.baidu. 是XX的二级域名,指向XX贴吧的服务器。/p/3138733512是服务器某个资源,即这个帖子的地址定位符se
18、e_lz和pn是该URL的两个参数,分别代表了只看楼主和帖子页码,等于1表示该条件为真所以我们可以把URL分为两局部,一局部为根底局部,一局部为参数局部。例如,上面的URL我们划分根底局部是tieba.baidu./p/3138733512,参数局部是?see_lz=1&pn=1熟悉了URL的格式,那就让我们用urllib2库来试着抓取页面内容吧。上一篇糗事百科我们最后改成了面向对象的编码方式,这次我们直接尝试一下,定义一个类名叫BDTB(XX贴吧),一个初始化方法,一个获取页面的方法。其中,有些帖子我们想指定给程序是否要只看楼主,所以我们把只看楼主的参数初始化放在类的初始化上,即init方法
19、。另外,获取页面的方法我们需要知道一个参数就是帖子页码,所以这个参数的指定我们放在该方法中。综上,我们初步构建出根底代码如下:123456789101112131415161718192021222324252627282930_author_ =CQC# -*- coding:utf-8 -*-importurllibimporturllib2importre#XX贴吧爬虫类classBDTB:#初始化,传入基地址,是否只看楼主的参数def_init_(self,baseUrl,seeLZ):self.baseURL =baseUrlself.seeLZ =?see_lz=+str(seeL
20、Z)#传入页码,获取该页帖子的代码defgetPage(self,pageNum):try:url =self.baseURL+self.seeLZ +&pn=+str(pageNum)request =urllib2.Request(url)response =urllib2.urlopen(request)printresponse.read()returnresponseexcepturllib2.URLError, e:ifhasattr(e,reason):returnNonebaseURL =tieba.baidu./p/3138733512bdtb =BDTB(baseURL,1)bdtb.getPage(1)运行代码,我们可以看到屏幕上打印出了这个帖子第一页楼主发言的所有内容,形式为HTML代码。1提取帖子标题首先,让我们提取帖子的标题。在浏览器中审查元素,或者按F12,查看页面源代码,我们找到标题所在的代码段,可以发现这个标题的HTML代码是1纯原创我心中的NBA2014-2015赛季现役5
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1