Python爬虫学习(5): 简单的爬取
学习了urllib,urlib2以及正则表达式之后就可以做一些简单的抓取以及处理工作。为了抓取方便,这里选择糗事百科的网页作为抓取对象。
1. 获取数据:
In [293]: url = "http://www.qiushibaike.com/hot"
# 如果不加入用户代理会报错
In [294]: headers = {"User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0"}
In [295]: request = urllib2.Request(url,headers=headers)
In [296]: response = urllib2.urlopen(request)
In [297]: content = response.read()
In [298]: print content
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="X-UA-Compatible" content="chrome=1,IE=edge">
<meta name="renderer" content="webkit"/>
<meta name="applicable-device" content="pc">
<title>
2. 抓取段子的文字内容:
我用的firefox浏览器,按F12,然后进入查看器,就可以对生成的页面代码进行查看,当点击某一项的时候会在网页中标注这一段代码会对应页面中哪一块。

段子都在id="content-left"的div之中,而其中的每一个子div都是一条段子。

我们展开其中的一条段子,这里将每一个段子区域划分为好几块:

其中class为contentHerf的<a>中有段子的内容,而我们要抓取就是这个中文内容。

2.1 获取段子文本内容
更具html结构我们写一个简单的获取段子文本内容的正则表达式:(?:<div.*?class=\"content\">)\s+.*?<span>(.*)<\/span>\s+.*?</div>
(?:<div.*class=\"content\">): 表示匹配分组中内容,但不记入匹配结果。上述表达式的蓝色部分是最终获取的结果
In [313]: pattern = re.compile(r"(?:<div.*class=\"content\">)\s+.*?<span>(.*)<\/span>\s+.*?</div>")
# 查找所有匹配结果
In [314]: result = re.findall(pattern,content)
In [315]: print result[0]
跟老婆正在吵架,老丈人碰巧来我家,三人面面相觑,场面十分尴尬,我正不知道该怎么说话,我老婆手机突然响了,那货直接按了免提,竟然是我岳母打来的,琴子,你爸有没有去你家?我刚跟他吵了一架,老家伙没吵赢,离家出走了!<br/>玛德,更尴尬了!!
\s+.*?的写法有点繁琐,这里在compile函数中加上r.S标志,将换行符号也纳入符号"."中,变换之后的写法如下:
pattern = re.compile(r"(?:<div.*?class=\"content\">).*?<span>(.*?)<\/span>.*?</div>",re.S)
在段子文本中有用<br/>表示的换行,需要将其替换为\n。这时候可以用sub函数。
In [319]: for item in result:
...: item = re.sub(re.compile(r"<br/>"),r"\n",item)
...: print item 跟老婆正在吵架,老丈人碰巧来我家,三人面面相觑,场面十分尴尬,我正不知道该怎么说话,我老婆手机突然响了,那货直接按了免提,竟然是我岳母打来的,琴子,你爸有没有去你家?我刚跟他吵了一架,老家伙没吵赢,离家出走了!
玛德,更尴尬了!!
..................
2.2 单独获取获取用户名:
In [354]: pattern = re.compile(r"(?:qiushi_tag_\d+).*?<h2>(.*?)</h2>",re.S)
In [355]: result = re.findall(pattern,content)
In [356]: len(result)
Out[356]: 20
In [357]: print result[0]
匪徒~入库君
2.3 同时获取用户名,段子文本内容,以及点赞数量和评论数量:
In [384]: pattern = re.compile(r"(?:qiushi_tag_\d+).*?<h2>(.*?)</h2>.*?(?:contentHerf).*?<span>(.*?)<\/span>.*?(?:class=\"stats\").*?<i.*?>(\d+)
...: </i>.*?<i.*?>(\d+)</i>",re.S) In [385]: result = re.findall(pattern,content) In [386]: for item in result:
...: print ""
...: print "用户:",item[0]
...: print "段子内容:\n",item[1]
...: print "点赞数量:",item[2]
...: print "评论数量:",item[3]
运行结果结果:

2.4 获取带图片的段子中的图片地址
不是每一个段子都会有图片。图片的的地址一般包含在class="thumb"的div块中
In [417]: pattern = re.compile(r"(?:class=\"thumb\").*?<img.*?src=\"(.*?)\"",re.S)
In [418]: result = re.findall(pattern,content)
In [419]:
# 此次抓取中只有五个有图片的段子
Out[419]:
['http://pic.qiushibaike.com/system/pictures/11778/117782282/medium/app117782282.jpg',
'http://pic.qiushibaike.com/system/pictures/11778/117783971/medium/app117783971.jpg',
'http://pic.qiushibaike.com/system/pictures/11778/117784294/medium/app117784294.jpg',
'http://pic.qiushibaike.com/system/pictures/11778/117782437/medium/app117782437.jpg',
'http://pic.qiushibaike.com/system/pictures/11778/117783530/medium/app117783530.jpg']
2.5 同时获取用户名,段子文本内容,以及图片地址,以及点赞数量和评论数量
由于不是每一个段子都会有图片,所以在抓取的时候有的则抓,有图片地址的时候才抓取地址。下边绿色的部分是抓取图片地址的主代码。
In [470]: pattern = re.compile(r"(?:qiushi_tag_\d+).*?<h2>(.*?)</h2>.*?(?:contentHerf).*?<span>(.*?)<\/span>.*?(?:class=\"thumb\".*?<img.*?src=\
"(.*?)\"(?:.*?))?(?:class=\"stats\").*?<i.*?>(\d+)</i>.*?<i.*?>(\d+)</i>",re.S) In [471]: result = re.findall(pattern,content) In [472]: for item in result:
...: print ""
...: print "用户:",item[0]
...: print "段子内容:\n",item[1]
...: print "段子中图片地址:",item[2]
...: print "点赞数量:",item[3]
...: print "评论数量:",item[4]

2.6 比较完全的抓取
下边的正则表达式子中绿色字样可以看着是不同字段的分割符号,特别标注部分就是对应获取字段的内容的部分。
In [522]: pattern = re.compile(r"(?:qiushi_tag_(\d+)).*?href=\"/users/(\d+)/\".*?img.*?src=\"(.*?)\".*?<h2>(.*?)</h2>.*?(?:contentHerf).*?<span>
...: (.*?)<\/span>.*?(?:class=\"thumb\".*?img.*?src=\"(.*?)\"(?:.*?))?(?:class=\"stats\").*?<i.*?>(\d+)</i>.*?<i.*?>(\d+)</i>",re.S) In [523]: result = re.findall(pattern,content) In [525]: for item in result:
...: print ""
...: print "段子ID:",item[0]
...: print "用户ID:",item[1]
...: print "用户头像:",item[2]
...: print "用户名:",item[3]
...: print "段子内容:\n",item[4]
...: print "段子中图片地址:",item[5]
...: print "点赞数量:",item[6]
...: print "评论数量:",item[7]

Python爬虫学习(5): 简单的爬取的更多相关文章
- Python爬虫学习三------requests+BeautifulSoup爬取简单网页
第一次第一次用MarkDown来写博客,先试试效果吧! 昨天2018俄罗斯世界杯拉开了大幕,作为一个伪球迷,当然也得为世界杯做出一点贡献啦. 于是今天就编写了一个爬虫程序将腾讯新闻下世界杯专题的相关新 ...
- Python爬虫学习之使用beautifulsoup爬取招聘网站信息
菜鸟一只,也是在尝试并学习和摸索爬虫相关知识. 1.首先分析要爬取页面结构.可以看到一列搜索的结果,现在需要得到每一个链接,然后才能爬取对应页面. 关键代码思路如下: html = getHtml(& ...
- 【python爬虫】一个简单的爬取百家号文章的小爬虫
需求 用"老龄智能"在百度百家号中搜索文章,爬取文章内容和相关信息. 观察网页 红色框框的地方可以选择资讯来源,我这里选择的是百家号,因为百家号聚合了来自多个平台的新闻报道.首先看 ...
- Python爬虫学习(6): 爬取MM图片
为了有趣我们今天就主要去爬取以下MM的图片,并将其按名保存在本地.要爬取的网站为: 大秀台模特网 1. 分析网站 进入官网后我们发现有很多分类: 而我们要爬取的模特中的女模内容,点进入之后其网址为:h ...
- 爬虫学习(二)--爬取360应用市场app信息
欢迎加入python学习交流群 667279387 爬虫学习 爬虫学习(一)-爬取电影天堂下载链接 爬虫学习(二)–爬取360应用市场app信息 代码环境:windows10, python 3.5 ...
- python爬虫实践(二)——爬取张艺谋导演的电影《影》的豆瓣影评并进行简单分析
学了爬虫之后,都只是爬取一些简单的小页面,觉得没意思,所以我现在准备爬取一下豆瓣上张艺谋导演的“影”的短评,存入数据库,并进行简单的分析和数据可视化,因为用到的只是比较多,所以写一篇博客当做笔记. 第 ...
- Python爬虫——使用 lxml 解析器爬取汽车之家二手车信息
本次爬虫的目标是汽车之家的二手车销售信息,范围是全国,不过很可惜,汽车之家只显示100页信息,每页48条,也就是说最多只能够爬取4800条信息. 由于这次爬虫的主要目的是使用lxml解析器,所以在信息 ...
- Python爬虫教程:验证码的爬取和识别详解
今天要给大家介绍的是验证码的爬取和识别,不过只涉及到最简单的图形验证码,也是现在比较常见的一种类型. 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻 ...
- Python爬虫开源项目代码,爬取微信、淘宝、豆瓣、知乎、新浪微博、QQ、去哪网等 代码整理
作者:SFLYQ 今天为大家整理了32个Python爬虫项目.整理的原因是,爬虫入门简单快速,也非常适合新入门的小伙伴培养信心.所有链接指向GitHub,祝大家玩的愉快 1.WechatSogou [ ...
- Python 爬虫实例(15) 爬取 百度百聘(微信公众号)
今天闲的无聊,爬取了一个网站,百度百聘,仅供学习参考 直接上代码: #-*-coding:utf-8-*- from common.contest import * def spider(): hea ...
随机推荐
- 【原】理解javascript中的闭包
闭包在javascript来说是比较重要的概念,平时工作中也是用的比较多的一项技术.下来对其进行一个小小的总结 什么是闭包? 官方说法: 闭包是指有权访问另一个函数作用域中的变量的函数.创建闭包的常见 ...
- Visual Studio 如何使用代码片段Code Snippet提高编程速度!!!
使用Code Snippet简化Coding 在开发的项目的时候,你是否经常遇到需要重复编写一些类似的代码,比如是否经常会使用 for.foreach ? 在编写这两个循环语句的时候,你是一个字符 ...
- 10月25日下午PHP静态、抽象、接口
多态(运行多态)概念:当父类引用指向子类实例,由于子类里面对父类的方法进行了重写,父类引用在调用该方法的时候表现出的不同状态.条件:1.必须发生在继承下2.必须重写父类方法3.父类引用调用该方法 如果 ...
- Eclipse DDT
http://www.eclipse.org/downloads/ https://github.com/DDT-IDE/DDT/blob/latest/documentation/UserGuide ...
- JavaScript 数组中的 indexOf 方法
let arr = ['orange', '2016', '2016']; arr.indexOf('orange'); //0 arr.indexOf('o'); //-1 arr.indexOf( ...
- nginx 和 IIS 实现负载均衡
Nginx的作用和优点,这里不必多说,今天主要是nginx负载均衡实验,把做的步骤记录下来,作为一个学习笔记吧,也可以给大家做下参考. 1.Nginx安装 1.下载地址:http://nginx.or ...
- 淘宝分布式NOSQL框架:Tair
Tair 分布式K-V存储方案 tair 是淘宝的一个开源项目,它是一个分布式的key/value结构数据的解决方案. 作为一个分布式系统,Tair由一个中心控制节点(config server)和一 ...
- 深入理解javascript原型和闭包(8)——简述【执行上下文】上
什么是“执行上下文”(也叫做“执行上下文环境”)?暂且不下定义,先看一段代码: 第一句报错,a未定义,很正常.第二句.第三句输出都是undefined,说明浏览器在执行console.log(a)时, ...
- 安装 Ruby, Rails 运行环境 常见的错误
安装部署ruby on rails 的环境时并不是想的那么顺利 这个是我遇到的问题及解决的方式 参考安装博客: (1) https://ruby-china.org/wiki/install_ruby ...
- ThinkPHP真正疑难问题笔记
如何选择线程安全版本还是非线程安全版本: http://www.cnblogs.com/Alight/p/3389113.html(看webserver处理请求时, 使用的是多线程的方式还是 多进程的 ...