python网络爬虫之使用scrapy自动爬取多个网页
前面介绍的scrapy爬虫只能爬取单个网页。如果我们想爬取多个网页。比如网上的小说该如何如何操作呢。比如下面的这样的结构。是小说的第一篇。可以点击返回目录还是下一页
对应的网页代码:
我们再看进入后面章节的网页,可以看到增加了上一页
对应的网页代码:
通过对比上面的网页代码可以看到. 上一页,目录,下一页的网页代码都在<div>下的<a>元素的href里面。不同的是第一章只有2个<a>元素,从二章开始就有3个<a>元素。因此我们可以通过<div>下<a>元素的个数来判决是否含有上一页和下一页的页面。代码如下
最终得到生成的网页链接。并调用Request重新申请这个网页的数据
那么在pipelines.py的文件中。我们同样需要修改下存储的代码。如下。可以看到在这里就不是用json. 而是直接打开txt文件进行存储
class Test1Pipeline(object):
def __init__(self):
self.file=''
def process_item(self, item, spider):
self.file=open(r'E:\scrapy_project\xiaoshuo.txt','wb')
self.file.write(item['content'])
self.file.close()
return item
完整的代码如下:在这里需要注意两次yield的用法。第一次yield后会自动转到Test1Pipeline中进行数据存储,存储完以后再进行下一次网页的获取。然后通过Request获取下一次网页的内容
class testSpider(Spider):
name="test1"
allowd_domains=['http://www.xunsee.com']
start_urls=["http://www.xunread.com/article/8c39f5a0-ca54-44d7-86cc-148eee4d6615/1.shtml"]
def parse(self, response):
init_urls="http://www.xunread.com/article/8c39f5a0-ca54-44d7-86cc-148eee4d6615"
sel=Selector(response)
context=''
content=sel.xpath('//div[@id="content_1"]/text()').extract()
for c in content:
context=context+c.encode('utf-8')
items=Test1Item()
items['content']=context
count = len(sel.xpath('//div[@id="nav_1"]/a').extract())
if count > 2:
next_link=sel.xpath('//div[@id="nav_1"]/a')[2].xpath('@href').extract()
else:
next_link=sel.xpath('//div[@id="nav_1"]/a')[1].xpath('@href').extract()
yield items
for n in next_link:
url=init_urls+'/'+n
print url
yield Request(url,callback=self.parse)
对于自动爬取网页scrapy有个更方便的方法:CrawlSpider
前面介绍到的Spider中只能解析在start_urls中的网页。虽然在上一章也实现了自动爬取的规则。但略显负责。在scrapy中可以用CrawlSpider来进行网页的自动爬取。
爬取的规则原型如下:
classscrapy.contrib.spiders.Rule(link_extractor, callback=None, cb_kwargs=None, follow=None,process_links=None, process_request=None)
LinkExtractor.:它的作用是定义了如何从爬取到的的页面中提取链接
Callback指向一个调用函数,每当从LinkExtractor获取到链接时将调用该函数进行处理,该回调函数接受一个response作为第一个参数。注意:在用CrawlSpider的时候禁止用parse作为回调函数。因为CrawlSpider使用parse方法来实现逻辑,因此如果使用parse函数将会导致调用失败
Follow是一个判断值,用来指示从response中提取的链接是否需要跟进
在scrapy shell中提取www.sina.com.cn为例
LinkExtractor中的allow只针对href属性:
例如下面的链接只针对href属性做正则表达式提取
结构如下:可以得到各个链接。
可以通过restrict_xpaths对各个链接加以限制,如下的方法:
实例2:还是以之前的迅读网为例
提取网页中的下一节的地址:
网页地址:
http://www.xunread.com/article/8c39f5a0-ca54-44d7-86cc-148eee4d6615/1.shtml
下一页的的相对URL地址为2.shtml。
通过如下规则提取出来
>>> item=LinkExtractor(allow=('\d\.shtml')).extract_links(response)
>>> for i in item:
... print i.ur
...
http://www.xunread.com/article/8c39f5a0-ca54-44d7-86cc-148eee4d6615/2.shtml
也通过导航页面直接获取所有章节的链接:
C:\Users\Administrator>scrapy shell http://www.xunread.com/article/8c39f5a0-ca54
-44d7-86cc-148eee4d6615/index.shtml
from scrapy.linkextractors import LinkExtractor
>>> item=LinkExtractor(allow=('\d\.shtml')).extract_links(response)
>>> for i in item:
... print i.url
得到如下全部的链接
那么接下来构造在scrapy中的代码,如下
class testSpider(CrawlSpider):
name="test1"
allowd_domains=['http://www.xunsee.com']
start_urls=["http://www.xunsee.com/article/8c39f5a0-ca54-44d7-86cc-148eee4d6615/1.shtml"]
rules=(Rule(LinkExtractor(allow=('\d\.shtml')),callback='parse_item',follow=True),)
print rules
def parse_item(self, response):
print response.url
sel=Selector(response)
context=''
content=sel.xpath('//div[@id="content_1"]/text()').extract()
for c in content:
context=context+c.encode('utf-8')
items=Test1Item()
items['content']=context
yield items
关键的是rules=(Rule(LinkExtractor(allow=('\d\.shtml')),callback='parse_item',follow=True),) 这个里面规定了提取网页的规则。以上面的例子为例。爬取的过程分为如下几个步骤:
1 从http://www.xunsee.com/article/8c39f5a0-ca54-44d7-86cc-148eee4d6615/1.shtml开始,第一调用parse_item,用xpath提取网页内容,然后用Rule提取网页规则,在这里提取到2.shtml。
2 进入2.shtml.进入2.shtml后再重复运行第一步的过程。直到Rules中提取不到任何规则
我们也可以做一下优化,设置start_urls为页面索引页面
http://www.xunsee.com/article/8c39f5a0-ca54-44d7-86cc-148eee4d6615/index.shtml
这样通过Rule可以一下提取出所有的链接。然后对每个链接调用parse_item进行网页信息提取。这样的效率比从1.shtml要高效很多。
python网络爬虫之使用scrapy自动爬取多个网页的更多相关文章
- python网络爬虫之使用scrapy自动登录网站
前面曾经介绍过requests实现自动登录的方法.这里介绍下使用scrapy如何实现自动登录.还是以csdn网站为例. Scrapy使用FormRequest来登录并递交数据给服务器.只是带有额外的f ...
- 爬虫(二)Python网络爬虫相关基础概念、爬取get请求的页面数据
什么是爬虫 爬虫就是通过编写程序模拟浏览器上网,然后让其去互联网上抓取数据的过程. 哪些语言可以实现爬虫 1.php:可以实现爬虫.php被号称是全世界最优美的语言(当然是其自己号称的,就是王婆 ...
- Python网络爬虫第三弹《爬取get请求的页面数据》
一.urllib库 urllib是Python自带的一个用于爬虫的库,其主要作用就是可以通过代码模拟浏览器发送请求.其常被用到的子模块在Python3中的为urllib.request和urllib. ...
- 【Python网络爬虫四】通过关键字爬取多张百度图片的图片
最近看了女神的新剧<逃避虽然可耻但有用>,同样男主也是一名程序员,所以很有共鸣 被大只萝莉萌的一脸一脸的,我们来爬一爬女神的皂片. 百度搜索结果:新恒结衣 本文主要分为4个部分: 1.下载 ...
- Python网络爬虫案例(二)——爬取招聘信息网站
利用Python,爬取 51job 上面有关于 IT行业 的招聘信息 版权声明:未经博主授权,内容严禁分享转载 案例代码: # __author : "J" # date : 20 ...
- python网络爬虫之使用scrapy爬取图片
在前面的章节中都介绍了scrapy如何爬取网页数据,今天介绍下如何爬取图片. 下载图片需要用到ImagesPipeline这个类,首先介绍下工作流程: 1 首先需要在一个爬虫中,获取到图片的url并存 ...
- 【python 网络爬虫】之scrapy系列
网络爬虫之scripy系列 [scrapy网络爬虫]之0 爬虫与反扒 [scrapy网络爬虫]之一 scrapy框架简介和基础应用 [scrapy网络爬虫]之二 持久化操作 [scrapy网络爬虫]之 ...
- Python 网络爬虫 008 (编程) 通过ID索引号遍历目标网页里链接的所有网页
通过 ID索引号 遍历目标网页里链接的所有网页 使用的系统:Windows 10 64位 Python 语言版本:Python 2.7.10 V 使用的编程 Python 的集成开发环境:PyChar ...
- python3编写网络爬虫14-动态渲染页面爬取
一.动态渲染页面爬取 上节课我们了解了Ajax分析和抓取方式,这其实也是JavaScript动态渲染页面的一种情形,通过直接分析Ajax,借助requests和urllib实现数据爬取 但是javaS ...
随机推荐
- Struts2之Action接收请求参数和拦截器
技术分析之在Struts2框架中使用Servlet的API 1. 在Action类中也可以获取到Servlet一些常用的API * 需求:提供JSP的表单页面的数据,在Ac ...
- redis中键的生存时间(expire)
1.redis中可以使用expire命令设置一个键的生存时间,到时间后redis会自动删除它 expire 设置生存时间(单位/秒) pexpire 设置生存时间(单位/毫秒) ttl/pttl 查看 ...
- Shell脚本编写
1.什么是Shell脚本 Shell脚本是利用 shell 的功能所写的一个程序 program,这个程序是使用纯文本文件,将一些 shell 的语法与指令(含外部指令)写在里面, 搭配正则表达式.管 ...
- [玩耍]C++控制台扫雷
其实是大一还不会GUI时闲着无聊写的.都是硬编码,也不支持自定义棋盘大小,现在看看这代码惨不忍睹.下载地址:http://download.csdn.net/download/xienaoban/98 ...
- ArcGIS 网络分析[1.5] 使用点线数据一起创建网络数据集(如何避免孤立点/点与线的连通性组合结果表)
ArcGIS中最基本的三种矢量数据是什么?点线面. 网络中除了路网之外,还会有地物点. 如上图,我们在建立网络数据集的时候,作为实验,当然可以只是公路网.但是在大型的决策任务中,网络数据集就不只是公路 ...
- 学习MVC之租房网站(十)-预约和跟单
在上一篇<学习MVC之租房网站(九)-房源显示和搜索>完成了房源的显示.检索,然后是用户的预约看房,以及后台操作员对预约看房的跟单操作. 预约看房仅有将预约信息保存到对应表的操作,预约表有 ...
- Oracle 12C 新特性之 PDB热克隆(本地克隆、远端异机克隆)
说明:版本12.2.0.1 12c r1版本中 clone 一份PDB源库需要打开在read only只读模式 , 在12c r2版本中引入了local undo mode, 源PDB在read/wr ...
- 编程语言与C语言的简介
1.什么是程序 指挥计算机执行我们想要它做的动作,而依照顺序执行的一组指令 2.程序的作用是什么 指挥计算机工作 3.程序的特征 1.程序是一行一行的执行 2.是一种与计算机沟通的语言 3.程序是由特 ...
- Servlet路径映射
Serlvlet路径映射 当一个请求发送到servlet容器的时候,容器先会将请求的url减去当前应用上下文的路径作为servlet的映射url. 容器默认请求的是一个Servlet,所以不会直接根据 ...
- iOS系统原生 二维码的生成、扫描和读取(高清、彩色)
由于近期工作中遇到了个需求:需要将一些固定的字段 在多个移动端进行相互传输,所以就想到了 二维码 这个神奇的东东! 现在的大街上.连个摊煎饼的大妈 都有自己的二维码来让大家进行扫码支付.可见现在的二维 ...