Python scrapy增量爬取实例及实现过程解析
这篇文章主要介绍了Pythonscrapy增量爬取实例及实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
开始接触爬虫的时候还是初学Python的那会,用的还是request、bs4、pandas,再后面接触scrapy做个一两个爬虫,觉得还是框架好,可惜都没有记录都忘记了,现在做推荐系统需要爬取一定的文章,所以又把scrapy捡起来。趁着这次机会做一个记录。
目录如下:
- 环境
 - 本地窗口调试命令
 - 工程目录
 - xpath选择器
 - 一个简单的增量爬虫示例
 - 配置介绍
 
环境
自己的环境下安装scrapy肯定用anaconda(再次强调anaconda的优越性
本地窗口调试与运行
开发的时候可以利用scrapy自带的调试功能进行模拟请求,这样request、response都会与后面代码保持一样。
#测试请求某网站 scrapyshellURL #设置请求头 scrapyshell-sUSER_AGENT="Mozilla/5.0(WindowsNT10.0;Win64;x64;rv:61.0)Gecko/20100101Firefox/61.0"URL #指定爬虫内容输出文件格式(json、csv等 scrapycrawlSPIDER_NAME-oFILE_NAME.csv #创建爬虫工程 scrapystartprojectarticles#在当前目录创建一个scrapy工程
新工程结构介绍
#spiders文件下存放所有爬虫,item.py格式化数据输出 #middlewares.py设置请求细节(请求头之类的),pipelines.py为数据输出的管道,每一个封装好的item都会经过这里 #settings.py对工程进行全局设置(存放配置 ├──articles │├──articles ││├──__init__.py ││├──items.py ││├──middlewares.py ││├──pipelines.py ││├──settings.py ││└──spiders ││├──healthy_living.py ││├──__init__.py ││└──people_health.py │└──scrapy.cfg ├──README.en.md └──README.md
页面解析神器——Xpath选择器
scrapy自带xpath选择器,很方便,简单介绍一些常用的
#全站爬取神器--LinkExtractor,可以自动获取该标签下的所有url跟text(因为网站结构大都一个套路
fromscrapy.linkextractorsimportLinkExtractor
le=LinkExtractor(restrict_xpaths="//ul[@class='nav2_UL_1clearFix']")#返回一个迭代器,通过循环(foriinle),可获取url(i.url)(i.text)
#获取属性class为所有aa的div标签内容中的内容
response.xpath("//div[@class='aa']/text()").extract()#'//'代表获取所有,'/'代表获取第一个,类似的可以找属性为ul的其它标签
#获取内容包含“下一页”的所有a标签中包含的链接(提取下一页链接神器
response.xpath("//a[contains(text(),'下一页')]/@href").extract()
一个简单的增量爬取示例
这里增量爬取的思想很简单:目标网站的数据都是按照时间排列的,所以在对某个连接进行request之前,先查询数据库中有没有这条数据,如果有,就停止爬虫,如果没有发起请求
classHealthyLiving(scrapy.Spider):
#一定要一个全局唯一的爬虫名称,命令行启动的时候需要指定该名称
name="healthy_living"
#指定爬虫入口,scrapy支持多入口,所以一定是lis形式
start_urls=['http://www.jkb.com.cn/healthyLiving/']
'''
抓取大类标签入口
'''
defparse(self,response):
le=LinkExtractor(restrict_xpaths="//ul[@class='nav2_UL_1clearFix']")
forlinkinle.extract_links(response)[1:-1]:
tag=link.text
#将这一级提取到的信息,通过请求头传递给下一级(这里是为了给数据打标签
meta={"tag":tag}
#依次解析每一个链接,并传递到下一级进行继续爬取
yieldscrapy.Request(link.url,callback=self.parse_articles,meta=meta)
'''
抓取页面内的文章链接及下一页链接
'''
defparse_articles(self,response):
#接收上一级传递的信息
meta=response.meta
article_links=response.xpath("//div[@class='txt']/h4/a/@href").extract()
forlinkinarticle_links:
res=self.collection.find_one({"article_url":link},{"article_url":1})
full_meta=dict(meta)
#将文章链接传入下一级
full_meta.update({"article_url":link})
ifresisNone:
yieldscrapy.Request(link,callback=self.parse_article,meta=full_meta)
else:
return
next_page=response.xpath("//div[@class='page']//a[contains(text(),'»')]/@href").extract()[0]
ifnext_page:
yieldscrapy.Request(next_page,callback=self.parse_articles,meta=meta)
#最后解析页面,并输出
defparse_article(self,response):
#从item.py中导入数据封装格式
article_item=ArticlesItem()
meta=response.meta
#利用xpath提取页面信息并封装成item
try:
article_item["tag"]=""
#...省略
finally:
yieldarticle_item
工程配置介绍
设置请求头、配置数据库
#设置请求头,在middlewares.py中设定,在settings.py中启用
classRandomUA(object):
user_agents=[
"Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit"
"/537.36(KHTML,likeGecko)Chrome/39.0.2171.71Safari/537.36",
"Mozilla/5.0(X11;Linuxx86_64)AppleWebKit/537.11(KHTML,likeGecko)Chrome/23.0.1271.64Safari/537.11",
"Mozilla/5.0(Windows;U;WindowsNT6.1;en-US)AppleWebKit"
"/534.16(KHTML,likeGecko)Chrome/10.0.648.133Safari/534.16"
]
defprocess_request(self,request,spider):
request.headers["User-Agent"]=random.choice(self.user_agents)
#设置数据入库处理,在pipeline.py进行配置,在settings.py进行启用
classMongoPipeline(object):
def__init__(self,mongo_uri,mongo_db):
self.mongo_uri=mongo_uri
self.mongo_db=mongo_db
@classmethod
deffrom_crawler(cls,crawler):
returncls(
mongo_uri=crawler.settings.get('MONGO_URI'),
mongo_db=crawler.settings.get('MONGO_DB')
)
defopen_spider(self,spider):
print("开始爬取",datetime.datetime.now().strftime('%Y-%m-%d%H:%M:%S'))
self.client=pymongo.MongoClient(self.mongo_uri)
self.db=self.client[self.mongo_db]
defprocess_item(self,item,spider):
data=self.db[item.collection].find_one({"title":item["title"],"date":item["date"]})
ifdataisNone:
self.db[item.collection].insert(dict(item))
#else:
#self.close_spider(self,spider)
returnitem
defclose_spider(self,spider):
print("爬取结束",datetime.datetime.now().strftime('%Y-%m-%d%H:%M:%S'))
self.client.close()
#在settings.py启动:请求头的修改,数据库的配置
DOWNLOADER_MIDDLEWARES={
#'articles.middlewares.ArticlesDownloaderMiddleware':543,
'articles.middlewares.RandomUA':543,#543代表优先级,数字越低优先级越高
}
ITEM_PIPELINES={
'articles.pipelines.MongoPipeline':300,
}
#一些其它配置
ROBOTSTXT_OBEY=True#是否遵守网站的robot协议
FEED_EXPORT_ENCODING='utf-8'#指定数据输出的编码格式
##数据库配置
MONGO_URI=''
MONGO_DB=''
MONGO_PORT=27017
MONGO_COLLECTION=''
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。