2019独角兽企业重金招聘Python工程师标准>>>

最近几天开始用Python3改写网上用Python2写的案例,发现完全可以用Python3来重构Python2的源码。本篇文章,借用一篇《Python爬虫实战一之爬取糗事百科段子》博文,写出它的Python3版本。这是一篇非常好的文章,从局部开始,然后逐步完成一个案例。下面就是它的Python3实现~

本篇目标

1.抓取糗事百科热门段子

2.过滤带有图片的段子

3.实现每按一次回车显示一个段子的发布时间,发布人,段子内容,点赞数。

糗事百科是不需要登录的,所以也没必要用到Cookie,另外糗事百科有的段子是附图的,我们把图抓下来图片不便于显示,那么我们就尝试过滤掉有图的段子吧。

好,现在我们尝试抓取一下糗事百科的热门段子吧,每按下一次回车我们显示一个段子。

1.确定URL并抓取页面代码

首先我们确定好页面的URL是 http://www.qiushibaike.com/hot/page/1,其中最后一个数字1代表页数,我们可以传入不同的值来获得某一页的段子内容。

import urllib.requestpage = 1
url = 'http://www.qiushibaike.com/hot/page/' + str(page)
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = { 'User-Agent' : user_agent }
try:request = urllib.request.Request(url,headers = headers)response = urllib.request.urlopen(request).read()content=response.decode('utf-8')    print(content)
except urllib.error.URLError as e:if hasattr(e,"code"):print e.codeif hasattr(e,"reason"):print e.reason

2.提取某一页的所有段子

好,获取了HTML代码之后,我们开始分析怎样获取某一页的所有段子。

首先我们审查元素看一下,按浏览器的F12,截图如下

我们可以看到,每一个段子都是<div class=”article block untagged mb15″ id=”…”>…</div>包裹的内容。
现在我们想获取发布人,发布日期,段子内容,以及点赞的个数。不过另外注意的是,段子有些是带图片的,如果我们在控制台显示图片是不现实的,所以我们直接把带有图片的段子给它剔除掉,只保存仅含文本的段子。所以我们加入如下正则表达式来匹配一下,用到的方法是 re.findall 是找寻所有匹配的内容。方法的用法详情可以看前面说的正则表达式的介绍。下面内容在我前面的博客中有介绍,就是利用re模块正则表达式检索捕获的页面内容:

pattern = re.compile('<div.*?class="author.*?>.*?<a.*?</a>.*?<a.*?>(.*?)</a>.*?<div.*?class'+'="content".*?title="(.*?)">(.*?)</div>(.*?)<div class="stats.*?class="number">(.*?)</i>',re.S)
items = re.findall(pattern,content)
for item in items:print(item[0]+item[1]+item[2]+item[3]+item[4])

现在正则表达式在这里稍作说明

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

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

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

现在我们可以看一下部分运行结果

儒雅男神 2015-02-17 14:34:42

小时候一个一个拆着放的举个爪…

<div class=”thumb”>

<a href=”/article/100705418?list=hot&s=4747301″ target=”_blank” οnclick=”_hmt.push([‘_trackEvent’, ‘post’, ‘click’, ‘signlePost’])”>
<img src=”http://pic.qiushibaike.com/system/pictures/10070/100705418/medium/app100705418.jpg” alt=”糗事#100705418″ />
</a>

</div>

7093
奇怪的名字啊 2015-02-17 14:49:16

回家的路,你追我赶,回家的心情和窗外的阳光一样灿烂。一路向前,离亲人越来越近了。哪里有爸妈哪里才是家,希望所有糗友的爸爸妈妈都身体健康…….

4803

这是其中的两个段子,分别打印了发布人,发布时间,发布内容,附加图片以及点赞数。其中,附加图片的内容我把图片代码整体抠了出来,这个对应item[3],所以我们只需要进一步判断item[3]里面是否含有img这个字样就可以进行过滤了。好,我们再把上述代码中的for循环改为下面的样子:

for item in items:haveImg = re.search("img",item[3])if not haveImg:print(item[0]+item[1]+item[2]+item[4])

现在整体代码如下:

import urllib.request
import repage = 1
url = 'http://www.qiushibaike.com/hot/page/' + str(page)
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = { 'User-Agent' : user_agent }
try:request = urllib.request.Request(url,headers = headers)response = urllib.request.urlopen(request)content = response.read().decode('utf-8')pattern = re.compile('<div.*?class="author.*?>.*?<a.*?</a>.*?<a.*?>(.*?)</a>.*?<div.*?class'+'="content".*?title="(.*?)">(.*?)</div>(.*?)<div class="stats.*?class="number">(.*?)</i>',re.S)items = re.findall(pattern,content)for item in items:haveImg = re.search("img",item[3])if not haveImg:print(item[0]+item[1]+item[2]+item[4])
except urllib.error.URLError as e:if hasattr(e,"code"):print e.codeif hasattr(e,"reason"):print e.reason

运行一下看下效果,已经剔除掉含图片的段子

3.完善交互,设计面向对象模式

好啦,现在最核心的部分我们已经完成,最后要设计出:按下回车,读取一个段子,显示出段子的发布人,发布日期,内容以及点赞个数。另外我们需要设计面向对象模式,引入类和方法,将代码做一下优化和封装,最后,我们的代码如下所示:

#!/usr/bin/env python3
__author__="BALUW"
import urllib.request
import urllib
import re#糗事百科爬虫类
class QSSPider:def __init__(self):self.pageIndex=1self.user_agent='Mozilla/4.0(compatible:MSIE 5.5;Windows NT)'#初始化headersself.headers={'User-Agent':self.user_agent}#存放段子的变量,每一个元素是每一页的段子们self.stories=[]#存放程序是否继续进行的变量self.enable=False#传入某一页的索引,获得页面代码#返回页面代码def getPage(self,pageIndex ):try:   url="http://www.qiushibaike.com/hot/page/"+str(pageIndex)request=urllib.request.Request(url,headers=self.headers)response=urllib.request.urlopen(request).read()pageCode=response.decode("utf-8")return pageCodeexcept urllib.error.URLError as e:if hasattr(e,"reason"):print("连接糗事百科失败,错误原因:",e.reason)return None#传入某一页代码,返回本页不带图片的段子列表#返回段子列表def getPageItems(self,pageIndex):pageStories=[]pageCode=self.getPage(pageIndex)if not pageCode:print("页面加载失败…………")pattern=re.compile('<div.*?class="author.*?>.*?<a.*?</a>.*?<a.*?>(.*?)</a>.*?<div.*?class'+'="content".*?title="(.*?)">(.*?)</div>(.*?)<div class="stats.*?class="number">(.*?)</i>',re.S)items=re.findall(pattern,pageCode)for item in items:haveImg=re.search("img",item[3])if not haveImg:#item[0]是一个段子的发布者,item[1]是发布时间,item[2]是内容,item[4]是点赞数pageStories.append([item[0].strip(),item[1].strip(),item[2].strip(),item[4].strip()])return pageStories#加载并提取页面内容,加入到列表中def loadPage(self):#如果当前未看的页数少于2页,则加载新一页if self.enable==True:if len(self.stories)<2:pageStories=self.getPageItems(self.pageIndex)#将该页面的段子放入全局list中if pageStories:self.stories.append(pageStories)self.pageIndex+=1#调用该方法,每次敲击回车打印输出一个段子def getOneStory(self,pageStories,page):#遍历一页的段子for story in pageStories:#等待用户输入inputx=input()#每当输入一次回车,判断一下是否要加载新页面self.loadPage()#输入Q则程序结束if inputx=="Q":self.enable=Falsereturnprint("第{0}页\t发布人:{1}\t发布时间:{2}\n{3}\n赞:{4}\n".format(page,story[0],story[1],story[2],story[3]))def start(self):print("正在读取糗事百科,按回车查看新段子,Q退出")#使变量为True,程序可以正常运行self.enable=True#先载入一个页面的段子self.loadPage()nowPage=0while self.enable:if len(self.stories)>0:#从全局list中获取一页的段子pageStories=self.stories[0]nowPage+=1#将全局list中第一个元素删除,因为已经取出del self.stories[0]#输出该页的段子self.getOneStory(pageStories,nowPage)#--------程序入口---------
print("""
------------------------------------程序:糗百爬虫  版本:1.1  作者:baluw  日期:2015-04-19  语言:Python 3.4   功能:捕获糗事百科上的文字段子
------------------------------------
""")
spider=QSSPider()
spider.start()
#--------程序入口---------

看看运行效果【这个是我用Python3改写的,不是原博客的,原文章真是好文章,因为它解决了我前一篇文章中存在的问题,并且代码更加优美】:

转载于:https://my.oschina.net/lifeisshort/blog/403627

Python3写爬虫(五)爬取糗事百科段子相关推荐

  1. 【网络爬虫】爬取糗事百科段子

    1.前言 自动爬取糗事百科段子,使用Python编写. 输出文件路径需根据实际自己修改哦,默认的是输出100条段子,终止条件可以自己设置. 另糗事百科可能会改版,如有问题,欢迎留言,或者自行更改正则表 ...

  2. python爬虫经典段子_玩转python爬虫之爬取糗事百科段子

    大家好,前面入门已经说了那么多基础知识了,下面我们做几个实战项目来挑战一下吧.那么这次为大家带来,Python爬取糗事百科的小段子的例子. 首先,糗事百科大家都听说过吧?糗友们发的搞笑的段子一抓一大把 ...

  3. 网络爬虫---爬取糗事百科段子实战

    Python网络爬虫 1.知识要求 掌握python基础语法 熟悉urllib模块知识 熟悉get方法 会使用浏览器伪装技术 如果您对相关知识遗忘了,可以点上面的相关知识链接,熟悉一下. 2.爬取糗事 ...

  4. Python之爬取糗事百科段子实战

    "简说Python",选择"置顶/星标公众号" 福利干货,第一时间送达! 阅读本文大约6分钟,实战学习,老表建议你反复看,反复记,反复练. // 本文作者 王豪 ...

  5. Python爬虫实战一之爬取糗事百科段子

    点我进入原文 另外, 中间遇到两个问题: 1. ascii codec can't decode byte 0xe8 in position 0:ordinal not in range(128) 解 ...

  6. 转 Python爬虫实战一之爬取糗事百科段子

    静觅 » Python爬虫实战一之爬取糗事百科段子 首先,糗事百科大家都听说过吧?糗友们发的搞笑的段子一抓一大把,这次我们尝试一下用爬虫把他们抓取下来. 友情提示 糗事百科在前一段时间进行了改版,导致 ...

  7. Python爬虫实战之爬取糗事百科段子

    Python爬虫实战之爬取糗事百科段子 完整代码地址:Python爬虫实战之爬取糗事百科段子 程序代码详解: Spider1-qiushibaike.py:爬取糗事百科的8小时最新页的段子.包含的信息 ...

  8. 爬虫实战1:爬取糗事百科段子

    本文主要展示利用python3.7+urllib实现一个简单无需登录爬取糗事百科段子实例. 如何获取网页源代码 对网页源码进行正则分析,爬取段子 对爬取数据进行再次替换&删除处理易于阅读 0. ...

  9. 【Python爬虫系列教程 28-100】小姐姐带你入门爬虫框架Scrapy、 使用Scrapy框架爬取糗事百科段子

    文章目录 Scrapy快速入门 安装和文档: 快速入门: 创建项目: 目录结构介绍: Scrapy框架架构 Scrapy框架介绍: Scrapy框架模块功能: Scrapy Shell 打开Scrap ...

最新文章

  1. 计算机编程导论python程序设计答案-学堂在线_计算机科学与Python编程导论_作业课后答案...
  2. python使用教程pandas-「Python」pandas入门教程
  3. VS2017离线包下载
  4. 安装ESXI 5.1
  5. 四、数据挖掘中常见的挖掘模式
  6. JS JAVASCRIPT 判断两个日期相隔多少天
  7. [css] 解释下css3的flexbox(弹性盒布局模型),以及它应用场景有哪些?
  8. 不属于python第三方程序_安装 selenium 对于python而言属于一个第三方的模块
  9. Unity中LitJson的使用
  10. 大数据整合方案架构总结
  11. android 仿微信加载框,Android仿微信网络加载弹出框
  12. 不再年轻,仍从头再来
  13. lua-switch功能实现
  14. EVE-NG环境搭建
  15. session如何设置超时时间
  16. SPA SEO SSR三者有什么区别
  17. 如何完善培训开发系统
  18. 为树莓派打实时preempt_rt补丁
  19. Shell脚本(一)
  20. xlwings跨工作簿复制粘贴工作表——小白文章

热门文章

  1. 诺奖得主罗杰错了?“宇宙在大爆炸之前就存在”毫无根据可言!
  2. 【并发编程】Thread类的详细介绍
  3. MySQL慢查询日志每天定时切割
  4. session和sessionID以及cookie的关系
  5. OpenCV 生成水墨质感的图片 黑暗之魂三 只狼:影逝二度
  6. (006)网络编程,反射及其应用,MySQL数据库
  7. 离线安装percona-toolkit
  8. 1计算机等级考试 12月,2017年12月计算机二级MS Office考试上机冲刺题(1)
  9. Python(六) 函数
  10. 你想要的Python面试题都在这里了!