学习了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. <<< Oracle表创建、修改、删除基础操作

    表是数据库存储数据的基本单元,它对应于现实世界中的对象(如部门和雇员等).表按列进行定义,存储若干行数据.表中应该至少有一列.在 Oracle 中,表一般指的是一个关系型数据表.也可以生成临时表和对象 ...

  2. 创建文本注记TextElement

    1.创建一个字体 /// <summary> /// 字体设置 /// </summary> /// <param name="size">Th ...

  3. SDK 支付

    充值:用什么买什么 MSDK: Q点:百科 http://baike.baidu.com/link?url=Dw8ySUIvv6AAprULG_wnI7Mst61gG4bO2qzfpfi1j9xx6c ...

  4. [Unity] Shader(着色器)之固定管线

    在Unity中,固定管线Shader的性能是最好的. 什么是固定管线呢? 固定渲染管线 —— 这是标准的几何&光照(T&L)管线,功能是固定的,它控制着世界.视.投影变换及固定光照控制 ...

  5. Python之路【第二十篇】其他WEB框架

    WEB框架功能分析 WEB框架本质上,就是一个SOCKET Server WEB框架前面有WSGI或者是自己写的SOCKET,然后交给URL路由系统处理,然后交给某个函数或某个类,然后在模板里拿到模板 ...

  6. sublime text3好用的插件

    1.安装package control sublime text3 的安装方法,ctrl+`,调出控制台输入 import urllib.request,os; pf = 'Package Contr ...

  7. thinkphp自定义标签库

    thinkphp ~ php中 的类, 的成员变量, 本身是没有类型说明的, 那么我怎么知道它的类型呢? 或初始值呢? 通常在类定义中, 如果能给一个初始值的(对于已知简单类型的),最好给一个初始值, ...

  8. R入门<三>-R语言实战第4章基本数据管理摘要

    入门书籍:R语言实战 进度:1-4章 摘要: 1)实用的包 forecast:用于做时间序列预测的,有auto.arima函数 RODBC:可以用来读取excel文件.但据说R对csv格式适应更加良好 ...

  9. JavaScript 代码风格指南

    一.基本格式 缩进 建议每级4个空格,可以给编辑器设置tab = 4个空格,自动转换 分号 不要省略分号,防止ASI(自动插入分号)错误 行宽 每行代码不超过80个字符,过长应该用操作符手动断行 断行 ...

  10. java后端制作MD5加密

    由于一次业务的需要,我制作了一次密码的修改子业务. 当用户忘记密码的情况下,我需要动态的发给他一个6位的随机密码,通过即时通,短信,微信等.并同时修改数据库中的原密码为这6位的随机密码.让用户再去修改 ...