学习了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): 简单的爬取的更多相关文章

  1. Python爬虫学习三------requests+BeautifulSoup爬取简单网页

    第一次第一次用MarkDown来写博客,先试试效果吧! 昨天2018俄罗斯世界杯拉开了大幕,作为一个伪球迷,当然也得为世界杯做出一点贡献啦. 于是今天就编写了一个爬虫程序将腾讯新闻下世界杯专题的相关新 ...

  2. Python爬虫学习之使用beautifulsoup爬取招聘网站信息

    菜鸟一只,也是在尝试并学习和摸索爬虫相关知识. 1.首先分析要爬取页面结构.可以看到一列搜索的结果,现在需要得到每一个链接,然后才能爬取对应页面. 关键代码思路如下: html = getHtml(& ...

  3. 【python爬虫】一个简单的爬取百家号文章的小爬虫

    需求 用"老龄智能"在百度百家号中搜索文章,爬取文章内容和相关信息. 观察网页 红色框框的地方可以选择资讯来源,我这里选择的是百家号,因为百家号聚合了来自多个平台的新闻报道.首先看 ...

  4. Python爬虫学习(6): 爬取MM图片

    为了有趣我们今天就主要去爬取以下MM的图片,并将其按名保存在本地.要爬取的网站为: 大秀台模特网 1. 分析网站 进入官网后我们发现有很多分类: 而我们要爬取的模特中的女模内容,点进入之后其网址为:h ...

  5. 爬虫学习(二)--爬取360应用市场app信息

    欢迎加入python学习交流群 667279387 爬虫学习 爬虫学习(一)-爬取电影天堂下载链接 爬虫学习(二)–爬取360应用市场app信息 代码环境:windows10, python 3.5 ...

  6. python爬虫实践(二)——爬取张艺谋导演的电影《影》的豆瓣影评并进行简单分析

    学了爬虫之后,都只是爬取一些简单的小页面,觉得没意思,所以我现在准备爬取一下豆瓣上张艺谋导演的“影”的短评,存入数据库,并进行简单的分析和数据可视化,因为用到的只是比较多,所以写一篇博客当做笔记. 第 ...

  7. Python爬虫——使用 lxml 解析器爬取汽车之家二手车信息

    本次爬虫的目标是汽车之家的二手车销售信息,范围是全国,不过很可惜,汽车之家只显示100页信息,每页48条,也就是说最多只能够爬取4800条信息. 由于这次爬虫的主要目的是使用lxml解析器,所以在信息 ...

  8. Python爬虫教程:验证码的爬取和识别详解

    今天要给大家介绍的是验证码的爬取和识别,不过只涉及到最简单的图形验证码,也是现在比较常见的一种类型. 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻 ...

  9. Python爬虫开源项目代码,爬取微信、淘宝、豆瓣、知乎、新浪微博、QQ、去哪网等 代码整理

    作者:SFLYQ 今天为大家整理了32个Python爬虫项目.整理的原因是,爬虫入门简单快速,也非常适合新入门的小伙伴培养信心.所有链接指向GitHub,祝大家玩的愉快 1.WechatSogou [ ...

  10. Python 爬虫实例(15) 爬取 百度百聘(微信公众号)

    今天闲的无聊,爬取了一个网站,百度百聘,仅供学习参考 直接上代码: #-*-coding:utf-8-*- from common.contest import * def spider(): hea ...

随机推荐

  1. BZOJ2144: 跳跳棋

    传送门 神题一道. 考虑题目性质.首先对于一个状态,只存在四种情况,即最左/右边的点跳到中间,中间的点跳到左/右.而对于一个状态,显然第一种情况的两种分支不能同时存在,那么题目就可以理解为从$(a,b ...

  2. 【转】Java enum的用法详解

    用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fianl.... .现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法. p ...

  3. Excel 转Latex 及tex表格的处理 总结

    Excel 转LaTex表格 与TeX表格的处理 总结   工具使用:一个Latex表格输入神器--Excel2Tex插件的安装过程. 首先下载插件:http://www.ctan.org/tex-a ...

  4. Oracle 图形化以及命令行安装

    @(Oracle)[Install] Oracle 安装 相关版本说明 不同版本的Oracle需要安装在特定的系统版本之上. 如Oracle 11gR2的11.2.0.1.0需要安装在CentOS 5 ...

  5. MySQL提示:The server quit without updating PID file问题的解决办法(转载)

    MySQL提示:The server quit without updating PID file问题的解决办法 今天网站web页面提交内容到数据库,发现出错了,一直提交不了,数找了下原因,发现数据写 ...

  6. 清北学堂模拟赛day7 错排问题

    /* 考虑一下已经放回m本书的情况,已经有书的格子不要管他,考虑没有书的格子,不考虑错排有(n-m)!种,在逐步考虑有放回原来位置的情况,已经放出去和已经被占好的格子,不用考虑,剩下全都考虑,设t=x ...

  7. linux下共享库的注意点之-fpic

    在编译共享库必须加上-fpic.这是为什么呢? 首先看一个简单的例子: #include <stdio.h> int fun1() { printf("fun1\n") ...

  8. Ulink2 "No Ulink Device found" 解决办法

    一.背景 keil使用ULINK2调试的时候,提示 "No Ulink Device found", "error: flash download failed - Ta ...

  9. 如何设置phpMyAdmin自动登录和取消自动登录

    如何设置phpMyAdmin自动登录? 首先在根目录找到config.sample.inc.php复制一份文件名改为config.inc.php(如果已经存在 config.inc.php 文件,则直 ...

  10. git 教程(14)--解决冲突

    人生不如意之事十之八九,合并分支往往也不是一帆风顺的. 准备新的feature1分支,继续我们的新分支开发: