Python scrapy增量爬取实例及实现过程解析
作者:boardMan 发布时间:2022-11-12 21:58:39
标签:Python,scrapy,增量,爬取
这篇文章主要介绍了Python scrapy增量爬取实例及实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
开始接触爬虫的时候还是初学Python的那会,用的还是request、bs4、pandas,再后面接触scrapy做个一两个爬虫,觉得还是框架好,可惜都没有记录都忘记了,现在做推荐系统需要爬取一定的文章,所以又把scrapy捡起来。趁着这次机会做一个记录。
目录如下:
环境
本地窗口调试命令
工程目录
xpath选择器
一个简单的增量爬虫示例
配置介绍
环境
自己的环境下安装scrapy肯定用anaconda(再次强调anaconda的优越性
本地窗口调试与运行
开发的时候可以利用scrapy自带的调试功能进行模拟请求,这样request、response都会与后面代码保持一样。
# 测试请求某网站
scrapy shell URL
# 设置请求头
scrapy shell -s USER_AGENT="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" URL
# 指定爬虫内容输出文件格式(json、csv等
scrapy crawl SPIDER_NAME -o FILE_NAME.csv
# 创建爬虫工程
scrapy startproject articles # 在当前目录创建一个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(因为网站结构大都一个套路
from scrapy.linkextractors import LinkExtractor
le = LinkExtractor(restrict_xpaths="//ul[@class='nav2_UL_1 clearFix']")# 返回一个迭代器,通过循环(for i in le),可获取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之前,先查询数据库中有没有这条数据,如果有,就停止爬虫,如果没有发起请求
class HealthyLiving(scrapy.Spider):
# 一定要一个全局唯一的爬虫名称,命令行启动的时候需要指定该名称
name = "healthy_living"
# 指定爬虫入口,scrapy支持多入口,所以一定是lis形式
start_urls = ['http://www.jkb.com.cn/healthyLiving/']
'''
抓取大类标签入口
'''
def parse(self, response):
le = LinkExtractor(restrict_xpaths="//ul[@class='nav2_UL_1 clearFix']")
for link in le.extract_links(response)[1:-1]:
tag = link.text
# 将这一级提取到的信息,通过请求头传递给下一级(这里是为了给数据打标签
meta = {"tag": tag}
# 依次解析每一个链接,并传递到下一级进行继续爬取
yield scrapy.Request(link.url, callback=self.parse_articles, meta=meta)
'''
抓取页面内的文章链接及下一页链接
'''
def parse_articles(self, response):
# 接收上一级传递的信息
meta = response.meta
article_links = response.xpath("//div[@class='txt']/h4/a/@href").extract()
for link in article_links:
res = self.collection.find_one({"article_url": link}, {"article_url": 1})
full_meta = dict(meta)
# 将文章链接传入下一级
full_meta.update({"article_url": link})
if res is None:
yield scrapy.Request(link, callback=self.parse_article, meta=full_meta)
else:
return
next_page = response.xpath("//div[@class='page']//a[contains(text(),'»')]/@href").extract()[0]
if next_page:
yield scrapy.Request(next_page, callback=self.parse_articles, meta=meta)
# 最后解析页面,并输出
def parse_article(self, response):
# 从item.py中导入数据封装格式
article_item = ArticlesItem()
meta = response.meta
# 利用xpath提取页面信息并封装成item
try:
article_item["tag"] = ""
# ... 省略
finally:
yield article_item
工程配置介绍
设置请求头、配置数据库
# 设置请求头,在middlewares.py中设定,在settings.py中启用
class RandomUA(object):
user_agents = [
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit"
"/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11",
"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit"
"/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16"
]
def process_request(self, request, spider):
request.headers["User-Agent"] = random.choice(self.user_agents)
# 设置数据入库处理,在pipeline.py进行配置,在settings.py进行启用
class MongoPipeline(object):
def __init__(self, mongo_uri, mongo_db):
self.mongo_uri = mongo_uri
self.mongo_db = mongo_db
@classmethod
def from_crawler(cls, crawler):
return cls(
mongo_uri=crawler.settings.get('MONGO_URI'),
mongo_db=crawler.settings.get('MONGO_DB')
)
def open_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]
def process_item(self, item, spider):
data = self.db[item.collection].find_one({"title": item["title"], "date": item["date"]})
if data is None:
self.db[item.collection].insert(dict(item))
# else:
# self.close_spider(self, spider)
return item
def close_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 = ''
来源:https://www.cnblogs.com/CodeMLB/p/12088856.html


猜你喜欢
- 背景在vscode刚刚装好的时候,对于开发人员来说可能需要写一些模块的测试,而这个模块可能又引用了其他模块,如果是同级目录的话可能会出现Mo
- $attrs和inheritAttrs用法$attrs属性解释:包含了父作用域中不作为组件 props 或自定义事件的 attribute
- 有一张错误上报表,下面只将与本文相关的字段罗列如下:上报人(ReportPerson)、上报错误ID(ErrorID)、上报时间(Repor
- 目录前言第一步:查看所有 SSH-Key第二步:生成一个 ssh-key,用于配置公司的 GitLab第三步:Github 生成一个 SSH
- 本文实例为大家分享了Python将图片彩色转化为素描的具体代码,供大家参考,具体内容如下第一种:from PIL import Image,
- 本文介绍使用Python进行Socket网络编程,假设读者已经具备了基本的网络编程知识和Python的基本语法知识,本文中的代码如果没有说明
- PHP convert_cyr_string() 函数实例把字符串由一种字符集转换成另一种:<?php $str = "He
- 注意事项[object] * n 的时候并没有复制n-1个object,而是增加了n-1个对object的引用。例子说明目标:生成一个10*
- 本文实例讲述了Go语言实现定时器的方法。分享给大家供大家参考。具体实现方法如下:package mainimport ( &quo
- 本机中原pyinstaller版本为3.5版本,本打算通过 pip install --upgrade pyinstaller进行升级,竟然
- PHP中主要用strtr()和str_repalce()这两个函数替换字符串和数组,但你们都知道他们这两个函数的区别和用法吗?有不少文章在说
- 如下:将html文件下载后,使用BeauifulSoup读取文件,并且使用html.parsertmp_soup.select里面的参数为:
- 上一篇文章为大家介绍了 GoFrame gcache使用实践 | 缓存控制 淘汰策略 ,得到了大家积极的反馈。后续几篇文章再接再厉,仍然为大
- 今日需求其实就是把Word中的表格转到Excel中,顺便做一个调整。这个需求在实际工作中,很多人还是经常碰到的!如果单单是两个表格,那只要简
- 目录1. 术语说明2. 简单字段名2.1 简单字段名的说明2.2 省略字段名2.3 数字形式的简单字段名2.4 变量名形式的简单字段名2.5
- 上一次的错误太多,排版也出现了问题,重写了一遍,希望大家支持.循环遍历一个元素是开发中最常见的需求之一,那么让我们来看一个由框架BASE2和
- 什么是闭包:闭包是一个存在内部函数的引用关系。该引用指向的是外部函数的局部变量对象(前提是内部函数使用了外部函数的局部变量)闭包的作用:延长
- <!DOCTYPE html><html lang="en"><head> <
- 本文实例讲述了Python3.5变量、数据结构、条件和循环语句、break与continue语句。分享给大家供大家参考,具体如下:1、变量:
- 在一个Web App中,所有数据,包括用户信息、发布的日志、评论等,都存储在数据库中。在awesome-python-app中,我们选择My