Python 爬虫(六):Scrapy 爬取景区信息

Python 爬虫(六):Scrapy 爬取景区信息,第1张

概述  Scrapy是一个使用Python语言开发,为了爬取网站数据,提取结构性数据而编写的应用框架,它用途广泛,比如:数据挖掘、监测和自动化测试。安装使用终端命令pipinstallScrapy即可。Scrapy比较吸引人的地方是:我们可以根据需求对其进行修改,它提供了多种类型的爬虫基类,如:BaseSpid

 

 

Scrapy 是一个使用 Python 语言开发,为了爬取网站数据,提取结构性数据而编写的应用框架,它用途广泛,比如:数据挖掘、监测和自动化测试。安装使用终端命令 pip install Scrapy 即可。

Scrapy 比较吸引人的地方是:我们可以根据需求对其进行修改,它提供了多种类型的爬虫基类,如:BaseSpIDer、sitemap 爬虫等,新版本提供了对 web2.0 爬虫的支持。

1 Scrapy 介绍

 

1.1 组成

Scrapy Engine(引擎):负责 SpIDer、ItemPipeline、Downloader、Scheduler 中间的通讯,信号、数据传递等。

Scheduler(调度器):负责接受引擎发送过来的 Request 请求,并按照一定的方式进行整理排列、入队,当引擎需要时,交还给引擎。

Downloader(下载器):负责下载 Scrapy Engine(引擎) 发送的所有 Requests 请求,并将其获取到的 Responses 交还给 Scrapy Engine(引擎),由引擎交给 SpIDer 来处理。

SpIDer(爬虫):负责处理所有 Responses,从中解析提取数据,获取 Item 字段需要的数据,并将需要跟进的 URL 提交给引擎,再次进入 Scheduler(调度器)。

Item Pipeline(管道):负责处理 SpIDer 中获取到的 Item,并进行后期处理,如:详细解析、过滤、存储等。

Downloader MIDdlewares(下载中间件):一个可以自定义扩展下载功能的组件,如:设置代理、设置请求头等。

SpIDer MIDdlewares(SpIDer 中间件):一个可以自定扩展和 *** 作引擎和 SpIDer 中间通信的功能组件,如:自定义 request 请求、过滤 response 等。

总的来说就是:SpIDer 和 Item Pipeline 需要我们自己实现,Downloader MIDdlewares 和 SpIDer MIDdlewares 我们可以根据需求自定义。

1.2 流程梳理

1)SpIDer 将需要发送请求的 URL 交给 Scrapy Engine 交给调度器;

2)Scrapy Engine 将请求 URL 转给 Scheduler;

3)Scheduler 对请求进行排序整理等处理后返回给 Scrapy Engine;

4)Scrapy Engine 拿到请求后通过 MIDdlewares 发送给 Downloader;

5)Downloader 向互联网发送请求,在获取到响应后,又经过 MIDdlewares 发送给 Scrapy Engine。

6)Scrapy Engine 获取到响应后,返回给 SpIDer,SpIDer 处理响应,并从中解析提取数据;

7)SpIDer 将解析的数据经 Scrapy Engine 交给 Item Pipeline, Item Pipeline 对数据进行后期处理;

8)提取 URL 重新经 Scrapy Engine 交给Scheduler 进行下一个循环,直到无 URL 请求结束。

1.3 Scrapy 去重机制

Scrapy 提供了对 request 的去重处理,去重类 RFPDupeFilter 在 dupefilters.py 文件中,路径为:Python安装目录\lib\site-packages\scrapy ,该类里面有个方法 request_seen 方法,源码如下:

 
def request_seen(self, request):    # 计算 request 的指纹    fp = self.request_fingerprint(request)    # 判断指纹是否已经存在    if fp in self.fingerprints:        # 存在        return True    # 不存在,加入到指纹集合中    self.fingerprints.add(fp)    if self.file:        self.file.write(fp + os.linesep)

它在 Scheduler 接受请求的时候被调用,进而调用 request_fingerprint 方法(为 request 生成一个指纹),源码如下:

 
def request_fingerprint(request, include_headers=None):    if include_headers:        include_headers = tuple(to_bytes(h.lower())                                 for h in sorted(include_headers))    cache = _fingerprint_cache.setdefault(request, {})    if include_headers not in cache:        fp = hashlib.sha1()        fp.update(to_bytes(request.method))        fp.update(to_bytes(canonicalize_url(request.url)))        fp.update(request.body or b'')        if include_headers:            for hdr in include_headers:                if hdr in request.headers:                    fp.update(hdr)                    for v in request.headers.getList(hdr):                        fp.update(v)        cache[include_headers] = fp.hexdigest()    return cache[include_headers]

在上面代码中我们可以看到

 
fp = hashlib.sha1()...cache[include_headers] = fp.hexdigest()

它为每一个传递过来的 URL 生成一个固定长度的唯一的哈希值。再看一下  __init__ 方法,源码如下:

 
def __init__(self, path=None, deBUG=False):	self.file = None	self.fingerprints = set()	self.logdupes = True	self.deBUG = deBUG	self.logger = logging.getLogger(__name__)	if path:		self.file = open(os.path.join(path, 'requests.seen'), 'a+')		self.file.seek(0)		self.fingerprints.update(x.rstrip() for x in self.file)

我们可以看到里面有 self.fingerprints = set() 这段代码,就是通过 set 集合的特点(set 不允许有重复值)进行去重。

去重通过 dont_filter 参数设置,如图所示

dont_filter 为 False 开启去重,为 True 不去重。

2 快速上手

制作 Scrapy 爬虫需如下四步:

创建项目 :创建一个爬虫项目明确目标 :明确你想要抓取的目标(编写 items.py)制作爬虫 :制作爬虫开始爬取网页(编写 xxspIDer.py)存储内容 :设计管道存储爬取内容(编写pipelines.py)

我们以爬取去哪儿网北京景区信息为例,如图所示:

2.1 创建项目

在我们需要新建项目的目录,使用终端命令 scrapy startproject 项目名 创建项目,我创建的目录结构如图所示:

spIDers 存放爬虫的文件items.py 定义数据类型mIDdleware.py 存放中间件piplines.py 存放数据的有关 *** 作settings.py 配置文件scrapy.cfg 总的控制文件2.2 定义 Item

Item 是保存爬取数据的容器,使用的方法和字典差不多。我们计划提取的信息包括:area(区域)、sight(景点)、level(等级)、price(价格),在 items.py 定义信息,源码如下:

 
import scrapy
class TicketspIDerItem(scrapy.Item): area = scrapy.FIEld() sight = scrapy.FIEld() level = scrapy.FIEld() price = scrapy.FIEld() pass
2.3 爬虫实现

在 spIDers 目录下使用终端命令 scrapy genspIDer 文件名 要爬取的网址 创建爬虫文件,然后对其修改及编写爬取的具体实现,源码如下:

 
import scrapyfrom ticketSpIDer.items import TicketspIDerItem
class QunarSpIDer(scrapy.SpIDer): name = 'qunar' allowed_domains = ['piao.qunar.com'] start_urls = ['https://piao.qunar.com/ticket/List.htm?keyword=%E5%8C%97%E4%BA%AC®ion=&from=mpl_search_suggest']
def parse(self, response): sight_items = response.CSS('#search-List .sight_item') for sight_item in sight_items: item = TicketspIDerItem() item['area'] = sight_item.CSS('::attr(data-districts)').extract_first() item['sight'] = sight_item.CSS('::attr(data-sight-name)').extract_first() item['level'] = sight_item.CSS('.level::text').extract_first() item['price'] = sight_item.CSS('.sight_item_price em::text').extract_first() yIEld item # 翻页 next_url = response.CSS('.next::attr(href)').extract_first() if next_url: next_url = "https://piao.qunar.com" + next_url yIEld scrapy.Request( next_url, callback=self.parse )

简单介绍一下:

name:爬虫名allowed_domains:允许爬取的域名atart_urls:爬取网站初始请求的 url(可定义多个)parse 方法:解析网页的方法response 参数:请求网页后返回的内容

yIEld

在上面的代码中我们看到有个 yIEld,简单说一下,yIEld 是一个关键字,作用和 return 差不多,差别在于 yIEld 返回的是一个生成器(在 Python 中,一边循环一边计算的机制,称为生成器),它的作用是:有利于减小服务器资源,在列表中所有数据存入内存,而生成器相当于一种方法而不是具体的信息,占用内存小。

爬虫伪装

通常需要对爬虫进行一些伪装,我们也简单处理一下,介绍一个最简单的方法:

使用终端命令 pip install scrapy-fake-useragent 安装在 settings.py 文件中添加如下代码: 
DOWNLOADER_MIDDLEWARES = {    # 关闭默认方法    'scrapy.downloadermIDdlewares.useragent.UserAgentMIDdleware': None,     # 开启    'scrapy_fake_useragent.mIDdleware.RandomUserAgentMIDdleware': 400, }
2.4 保存数据

我们将数据保存到本地的 csv 文件中,csv 具体 *** 作可以参考:https://docs.python.org/zh-cn/3/library/csv.HTML,下面看一下具体实现。

首先,在 pipelines.py 中编写实现,源码如下:

 
import csv
class TicketspIDerPipeline(object): def __init__(self): self.f = open('ticker.csv', 'w', enCoding='utf-8', newline='') self.fIEldnames = ['area', 'sight', 'level', 'price'] self.writer = csv.DictWriter(self.f, fIEldnames=self.fIEldnames) self.writer.writeheader() def process_item(self, item, spIDer): self.writer.writerow(item) return item
def close(self, spIDer): self.f.close()

然后,将 settings.py 文件中如下代码:

 
ITEM_PIPElines = {    'ticketSpIDer.pipelines.TicketspIDerPipeline': 300,}

放开即可。

2.5 运行

我们在 settings.py 的同级目录下创建运行文件,名字自定义,放入如下代码:

 
from scrapy.cmdline import executeexecute('scrapy crawl 爬虫名'.split())

这个爬虫名就是我们之前在爬虫文件中的 name 属性值,最后在 Pycharm 运行该文件即可。

 

 

总结

以上是内存溢出为你收集整理的Python 爬虫(六):Scrapy 爬取景区信息全部内容,希望文章能够帮你解决Python 爬虫(六):Scrapy 爬取景区信息所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/langs/1183680.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存