Scrapy-spiders(爬虫)
来源:互联网 发布:qq旋风mac 迅雷下载 编辑:程序博客网 时间:2024/05/17 05:55
爬虫(Spiders)
Spider 类定义了如何爬取某个(或某些)网站。包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item)。 换句话说,Spider 就是您定义爬取的动作及分析某个网页(或者是有些网页)的地方。
对于spider,爬取循环做着下面的事情:
首先生成抓取第一个URL的初始 request,request 下载完成后生成 response ,然后指定对 response 要使用的回调函数。
通过调用
start_requests()
方法(默认情况下)为start_urls
中指定的URL生成初始的Request
以及将parse
方法作为请求的回调函数。在回调函数中,您将解析 Response(网页)并返回带有提取的数据的 dict,
Item
对象,Request
对象或这些对象的可迭代容器。这些请求还将包含回调(可能是相同的),然后由 Scrapy 下载,然后由指定的回调处理它们的响应。在回调函数中,您通常使用 选择器 来解析页面内容(但您也可以使用BeautifulSoup,lxml或您喜欢的任何解析器),并使用解析的数据生成 Item。
最后,从爬虫返回的 Item 通常将持久存储到数据库(在某些 Item Pipeline 中)或使用 Feed导出 写入文件。
虽然这个循环(或多或少)适用于任何种类的 spider,Scrapy 实现了不同种类的默认 spider 用于不同的需求。我们将在这里谈论这些类型。
scrapy.Spider
class scrapy.spiders.Spider
这是最简单的爬虫,每个其他爬虫必须继承该类(包括 Scrapy 自带的一些爬虫,以及你自己写的爬虫)。它不提供任何特殊功能。它只是提供了一个默认的
start_requests()
实现,它读取并请求爬虫的start_urls
属性,并为每个结果响应调用爬虫的parse
方法。name
定义此爬虫名称的字符串。爬虫名称是爬虫如何由 Scrapy 定位(和实例化),因此它必须是唯一的。但是,您可以生成多个相同的爬虫实例(instance),这没有任何限制。 name是spider最重要的属性,而且是必须的。
如果蜘蛛抓取单个网站(single domain),一个常见的做法是以该网站(domain)(加或不加 后缀 )来命名spider。 例如,如果爬取
mywebsite.com
,该爬虫通常会被命名为mywebsite
。注意!
在Python 2中,这必须是ASCII。
allowed_domains
可选。包含了此爬虫允许抓取的域的列表。 Requests for URLs not belonging to the domain names specified in this list won’t be followed if OffsiteMiddleware is enabled.
start_urls
URL列表。当没有指定特定 URL 时,爬虫将从从该列表中开始抓取。因此,爬取的第一个页面将是这里列出的某个 URL。后续的 URL 将根据包含在起始 URL 中的数据连续生成。
custom_settings
该设置是一个dict。运行此爬虫时改设置会覆盖项目级的设置。因为设置在实例化(instantiation)之前更新,所以它必须定义为类属性。
有关可用内置设置的列表,请参阅:[内置设置参考]。
crawler
此属性由初始化类后的类方法
from_crawler()
设置,并链接到此爬虫实例绑定到的Crawler
对象。Crawlers在项目中封装了很多组件,作为单一入口访问(例如扩展,中间件,信号管理器等)。有关详情,请参阅 Crawler API。
settings
运行此爬虫的配置。这是一个 Settings 实例,请参 设置 来了解详细介绍 。
logger
Python Logger 使用 Spider 的 name 创建。您可以使用它通过它发送日志消息,如从记录日志记录。
from_crawler
这是 Scrapy 用来创建 spider 的类方法。
您可能不需要直接复写它,因为默认实现充当
__init __()
方法的代理,使用给定的参数 args 和命名参数 kwargs 调用它。尽管如此,此方法会在新实例中设置 crawler 和 settings 属性,以便稍后在爬虫代码中访问它们。
参数:
- crawler(
Crawler
实例) -spider将绑定到的crawler - args(
list
) - 传递给__init __()
方法的参数 - kwargs(dict) - 传递给
__init __()
方法的关键字参数
start_requests
此方法必须返回一个可迭代对象(iterable),该对象包含了 spider 用于爬取的第一个Request。
当 spider 启动时且未指定特定的 URL 时,Scrapy 会调用该方法。如果指定了特定的 URL,则使用
make_requests_from_url()
来创建 Request 对象。此方法仅被调用一次,因此将其作为生成器实现是安全的。该方法的默认实现是使用
start_urls
的 url 生成 Request。如果您想要修改最初爬取某个网站的Request对象,您可以重写(override)该方法。例如,如果您需要在启动时通过使用POST请求登录,您可以:
class MySpider(scrapy.Spider): name = 'myspider' def start_requests(self): return [scrapy.FormRequest("http://www.example.com/login", formdata={'user': 'john', 'pass': 'secret'}, callback=self.logged_in)] def logged_in(self, response): # here you would extract links to follow and return Requests for # each of them, with another callback pass
make_requests_from_url(url)
该方法接受一个URL并返回用于爬取的
Request
对象。 该方法在初始化request时被start_requests()
调用,也被用于转化url为request。默认未被复写(overridden)的情况下,该方法返回的Request对象中,
parse()
作为回调函数,dont_filter参数也被设置为开启。 (详情参见Request
)。parse(response)
当response没有指定回调函数时,这是Scrapy用来处理下载的response的默认方法。
parse
方法负责处理response并返回所抓取的数据以及(/或)跟进的URL。Spider
对其他的Request的回调函数也有相同的要求。此方法以及任何其他Requestd的回调函数必须返回一个可迭代的
Request
或 dict 或 [Item
] 对象。参数:response(
Response
) - 用于分析的responselog(message[, level, component])
通过 Spider 的
logger
发送日志消息,保留向后兼容性。有关详细信息,请参阅Logging from Spiders
。closed(reason)
当spider关闭时,该函数被调用。 该方法提供了一个替代调用signals.connect()来监听 [
spider_closed
] 信号的快捷方式。- crawler(
让我们看一个例子:
import scrapyclass MySpider(scrapy.Spider): name = 'example.com' allowed_domains = ['example.com'] start_urls = [ 'http://www.example.com/1.html', 'http://www.example.com/2.html', 'http://www.example.com/3.html', ] def parse(self, response): self.logger.info('A response from %s just arrived!', response.url)
在单个回调函数中返回多个Request以及Item的例子:
import scrapyclass MySpider(scrapy.Spider): name = 'example.com' allowed_domains = ['example.com'] start_urls = [ 'http://www.example.com/1.html', 'http://www.example.com/2.html', 'http://www.example.com/3.html', ] def parse(self, response): for h3 in response.xpath('//h3').extract(): yield {"title": h3} for url in response.xpath('//a/@href').extract(): yield scrapy.Request(url, callback=self.parse)
除了 start_urls
,你也可以直接使用 start_requests()
; 您也可以使用 Items 来给予数据更多的结构性(give data more structure):
import scrapyfrom myproject.items import MyItemclass MySpider(scrapy.Spider): name = 'example.com' allowed_domains = ['example.com'] def start_requests(self): yield scrapy.Request('http://www.example.com/1.html', self.parse) yield scrapy.Request('http://www.example.com/2.html', self.parse) yield scrapy.Request('http://www.example.com/3.html', self.parse) def parse(self, response): for h3 in response.xpath('//h3').extract(): yield MyItem(title=h3) for url in response.xpath('//a/@href').extract(): yield scrapy.Request(url, callback=self.parse)
Spider arguments
Spider 可以接收参数来修改其行为。spider 参数的一些常见用法是定义起始URL或限制要爬取一部分网站,但它们可用于配置spider 的任何功能。
Spider参数使用 -a
选项通过 crawl
命令传递。例如:
scrapy crawl myspider -a category=electronics
spider 可以在他们的 init 方法中访问参数:
import scrapyclass MySpider(scrapy.Spider): name = 'myspider' def __init__(self, category=None, *args, **kwargs): super(MySpider, self).__init__(*args, **kwargs) self.start_urls = ['http://www.example.com/categories/%s' % category] # ...
默认的 init 方法将获取任何spider参数,并将它们作为 spider 的属性。上面的例子也可以写成如下:
import scrapyclass MySpider(scrapy.Spider): name = 'myspider' def start_requests(self): yield scrapy.Request('http://www.example.com/categories/%s' % self.category)
请记住,蜘蛛参数只能是字符串。蜘蛛自己不会做任何解析。如果要从命令行设置 start_urls 属性,则必须使用 ast.literal_eval 或 json.loads 之类将它解析为列表,并将它设置为属性,然后将其设置为属性。否则,你会导致迭代一个 start_urls 字符串(一个非常常见的python陷阱),导致每个字符被看作一个单独的url。
有效的用例是通过 HttpAuthMiddleware
设置 http auth 证书或 通过 UserAgentMiddleware
设置 user agent:
scrapy crawl myspider -a http_user=myuser -a http_pass=mypassword -a user_agent=mybot
Spider 参数也可以通过 Scrapyd schedule.json API 传递。请参阅 Scrapyd文档 。
Generic Spiders
Scrapy 自带一些有用的通用爬虫,你可以将自己的爬虫作为它们的子类。他们的目的是为一些常见的抓取案例提供方便的功能,例如根据某些规则跟踪网站上的所有链接,从 Sitemaps 抓取或解析XML / CSV Feed。
对于在下面的爬虫中使用的示例,我们假设你有一个项目,在 myproject.items
模块中声明一个 TestItem
:
import scrapyclass TestItem(scrapy.Item): id = scrapy.Field() name = scrapy.Field() description = scrapy.Field()
CrawlSpider
class scrapy.spiders.CrawlSpider
这是最常用的爬行常规网站的spider,因为它通过定义一组规则为跟进链接提供了一个方便的机制。它可能不是完全适合您的特定网站或项目,但它有足够多的几种通用情况,因此您可以以此为起点,根据需要覆盖更多的自定义功能,当然也可以实现自己的spider。
除了从Spider继承的属性(您必须指定),这个类支持一个新的属性:
rules
它是一个(或多个)
Rule
对象的列表。每个Rule
定义用于爬取网址的特定行为。Rule 对象如下所述。如果多个规则匹配相同的链接,则将根据它们在此属性中定义的顺序使用第一个。
该spider也提供了一个可复写(overrideable)的方法:
parse_start_url(response)
对于 start_urls 中url所对应的 response 调用此方法。它允许解析初始响应,并且必须返回 Item
对象,Request
对象或包含其中任何对象的iterable。
爬取规则(Crawling rules)
class scrapy.spiders.Rule(link_extractor, callback=None, cb_kwargs=None, follow=None, process_links=None, process_request=None)
link_extractor
是一个 链接提取器(Link Extractor)对象,它定义如何从要爬取的页面提取链接。callback
是一个 callable 或 string(在这种情况下,该spider中同名的函数将会被调用),使用 link_extractor 从 Response 对象中提取的每个链接将会调用该函数。该回调接函数收一个 response 作为它的第一个参数,并且必须返回一个包含Item
及(或)[Request
] 对象(或它们的任何子类)的列表。警告!
当编写爬虫规则时,避免使用 parse 作为回调,因为
CrawlSpider
使用parse方法本身来实现其逻辑。因此,如果您覆盖 parse 方法,crawl spider 将会运行失败。[
cb_kwargs
] 是一个包含要传递给回调函数(keyword argument)的关键字参数的dict。[
follow
] 是一个布尔值,指定了根据该规则从response提取的链接是否需要跟进。如果 [callable
] 为 None,则默认为 True,否则默认为 False。[
process_links
] 是一个 callable 或 string(在这种情况下,该spider中同名的函数将会被调用),使用 link_extractor 从 Response 对象中提取的每个链接列表调用它。这主要用于过滤目的。[
process_request
] 是一个 callable 或 string(在这种情况下,该spider中同名的函数将会被调用),它将被此规则提取的每个 request 调用,并且必须返回一个 request 或None(过滤出 request)。
CrawlSpider示例
现在让我们来看看一个带有 rule 的 CrawlSpider 示例:
import scrapyfrom scrapy.spiders import CrawlSpider, Rulefrom scrapy.linkextractors import LinkExtractorclass MySpider(CrawlSpider): name = 'example.com' allowed_domains = ['example.com'] start_urls = ['http://www.example.com'] rules = ( # Extract links matching 'category.php' (but not matching 'subsection.php') # and follow links from them (since no callback means follow=True by default). Rule(LinkExtractor(allow=('category\.php', ), deny=('subsection\.php', ))), # Extract links matching 'item.php' and parse them with the spider's method parse_item Rule(LinkExtractor(allow=('item\.php', )), callback='parse_item'), ) def parse_item(self, response): self.logger.info('Hi, this is an item page! %s', response.url) item = scrapy.Item() item['id'] = response.xpath('//td[@id="item_id"]/text()').re(r'ID: (\d+)') item['name'] = response.xpath('//td[@id="item_name"]/text()').extract() item['description'] = response.xpath('//td[@id="item_description"]/text()').extract() return item
该spider将从example.com的首页开始爬取,获取category以及item的链接并对后者使用 parse_item 方法。 当item获得返回(response)时,将使用XPath处理HTML并生成一些数据填入 Item 中。
XMLFeedSpider
XMLFeedSpider example
CSVFeedSpider
CSVFeedSpider example
SitemapSpider
SitemapSpider examples
- 【Scrapy】Spiders爬虫
- Scrapy-spiders(爬虫)
- Scrapy源码分析-Spiders爬虫中文文档(一)
- Scrapy爬虫框架教程(三)-- 调试(Debugging)Spiders
- 九.scrapy项目下spiders内多个爬虫同时运行
- scrapy学习--Spiders
- Scrapy spiders介绍
- 跟我学系列,走进Scrapy爬虫(六)Spiders爬虫
- scrapy学习--内置Spiders简介
- Scrapy学习笔记IV-Spiders
- Scrapy:一次性运行多个Spiders
- Scrapy:一次性运行多个Spiders
- scrapy爬虫
- Scrapy 爬虫
- scrapy爬虫
- 爬虫-scrapy
- Locally run all of the spiders in Scrapy
- python.scrapy 之crawlall命令执行所有的spiders
- Cloneable接口
- eslint 安装配置(JS代码质量检测工具)
- sizeof 是关键字不是函数
- java学习笔记五
- 基于CANoe的ECU Bootloader刷写软件
- Scrapy-spiders(爬虫)
- 蓝桥杯 2n皇后问题
- SpEL support in Spring Data JPA @Query definitions
- BZOJ 3629 [JLOI2014] 聪明的燕姿 dfs
- python paramiko 验证
- 关于JS在页面替换字符串的操作的注意点
- javascript基础3.0
- 整数快速幂——次方求模
- new/delete与malloc/free的异同