Python 爬虫框架Scrapy Spiders学习
Spider類定義了如何爬取某個(gè)(或某些)網(wǎng)站。包括了爬取的動(dòng)作(例如:是否跟進(jìn)鏈接)以及如何從網(wǎng)頁的內(nèi)容中提取結(jié)構(gòu)化數(shù)據(jù)(爬取item)。 換句話說,Spider就是您定義爬取的動(dòng)作及分析某個(gè)網(wǎng)頁(或者是有些網(wǎng)頁)的地方。
對(duì)spider來說,爬取的循環(huán)類似下文:
Spider參數(shù)
Spider可以通過接受參數(shù)來修改其功能。 spider參數(shù)一般用來定義初始URL或者指定限制爬取網(wǎng)站的部分。 您也可以使用其來配置spider的任何功能。
在運(yùn)行 crawl 時(shí)添加 -a 可以傳遞Spider參數(shù)。
舉個(gè)例子:
運(yùn)行 crawl 時(shí)傳遞Spider參數(shù)
:ls __init__.py __pycache__ spider_demo.py :scrapy crawl SpiderDemo -a filename=problem.txt --nolog :ls __init__.py __pycache__ problem.txt spider_demo.pySpider參數(shù)也可以通過Scrapyd的 schedule.json API來傳遞。
Spider
Spider是最簡單的spider。每個(gè)其他的spider必須繼承自該類(包括Scrapy自帶的其他spider以及您自己編寫的spider)。 Spider并沒有提供什么特殊的功能。 其僅僅請(qǐng)求給定的 start_urls/start_requests ,并根據(jù)返回的結(jié)果(resulting responses)調(diào)用spider的 parse 方法。
- name
定義spider名字的字符串(string)。spider的名字定義了Scrapy如何定位(并初始化)spider,所以其必須是唯一的。 不過您可以生成多個(gè)相同的spider實(shí)例(instance),這沒有任何限制。 name是spider最重要的屬性,而且是必須的。
如果該spider爬取單個(gè)網(wǎng)站(single domain),一個(gè)常見的做法是以該網(wǎng)站(domain)(加或不加 后綴 )來命名spider。 例如,如果spider爬取 mywebsite.com ,該spider通常會(huì)被命名為 mywebsite 。 - allowed_domains
可選。包含了spider允許爬取的域名(domain)列表(list)。 當(dāng) OffsiteMiddleware 啟用時(shí), 域名不在列表中的URL不會(huì)被跟進(jìn)。 - start_urls
URL列表。當(dāng)沒有制定特定的URL時(shí),spider將從該列表中開始進(jìn)行爬取。 因此,第一個(gè)被獲取到的頁面的URL將是該列表之一。 后續(xù)的URL將會(huì)從獲取到的數(shù)據(jù)中提取。 - start_requests()
該方法必須返回一個(gè)可迭代對(duì)象(iterable)。該對(duì)象包含了spider用于爬取的第一個(gè)Request。
當(dāng)spider啟動(dòng)爬取并且未制定URL時(shí),該方法被調(diào)用。 當(dāng)指定了URL時(shí),make_requests_from_url() 將被調(diào)用來創(chuàng)建Request對(duì)象。 該方法僅僅會(huì)被Scrapy調(diào)用一次,因此您可以將其實(shí)現(xiàn)為生成器。
該方法的默認(rèn)實(shí)現(xiàn)是使用 start_urls 的url生成Request。
如果您想要修改最初爬取某個(gè)網(wǎng)站的Request對(duì)象,您可以重寫(override)該方法。 例如,如果您需要在啟動(dòng)時(shí)以POST登錄某個(gè)網(wǎng)站,你可以這么寫: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 callbackpass - make_requests_from_url(url)
該方法接受一個(gè)URL并返回用于爬取的 Request 對(duì)象。 該方法在初始化request時(shí)被 start_requests() 調(diào)用,也被用于轉(zhuǎn)化url為request。
默認(rèn)未被復(fù)寫(overridden)的情況下,該方法返回的Request對(duì)象中, parse() 作為回調(diào)函數(shù),dont_filter參數(shù)也被設(shè)置為開啟。 (詳情參見 Request). - parse(response)
當(dāng)response沒有指定回調(diào)函數(shù)時(shí),該方法是Scrapy處理下載的response的默認(rèn)方法。
parse 負(fù)責(zé)處理response并返回處理的數(shù)據(jù)以及(/或)跟進(jìn)的URL。 Spider 對(duì)其他的Request的回調(diào)函數(shù)也有相同的要求。
該方法及其他的Request回調(diào)函數(shù)必須返回一個(gè)包含 Request 及(或) Item 的可迭代的對(duì)象。
參數(shù): response (Response) – 用于分析的response - log(message[, level, component])
使用 scrapy.log.msg() 方法記錄(log)message。 log中自動(dòng)帶上該spider的 name 屬性。 - closed(reason)
當(dāng)spider關(guān)閉時(shí),該函數(shù)被調(diào)用。 該方法提供了一個(gè)替代調(diào)用signals.connect()來監(jiān)聽 spider_closed 信號(hào)的快捷方式。 - custom_settings
內(nèi)置設(shè)定。 - crawler
這個(gè)方法是被from_crawler調(diào)用的。 - settings
- from_crawler(crawler, *args, **kwargs)
用來創(chuàng)建一個(gè)spiders的,可以不用覆蓋它,默認(rèn)會(huì)去掉用__init__方法。
CrawlSpider
class scrapy.contrib.spiders.CrawlSpider爬取一般網(wǎng)站常用的spider。其定義了一些規(guī)則(rule)來提供跟進(jìn)link的方便的機(jī)制。 也許該spider并不是完全適合您的特定網(wǎng)站或項(xiàng)目,但其對(duì)很多情況都使用。 因此您可以以其為起點(diǎn),根據(jù)需求修改部分方法。當(dāng)然您也可以實(shí)現(xiàn)自己的spider。
除了從Spider繼承過來的(您必須提供的)屬性外,其提供了新的屬性:
- rules
一個(gè)包含一個(gè)(或多個(gè)) Rule 對(duì)象的集合(list)。 每個(gè) Rule 對(duì)爬取網(wǎng)站的動(dòng)作定義了特定表現(xiàn)。 Rule對(duì)象在下邊會(huì)介紹。 如果多個(gè)rule匹配了相同的鏈接,則根據(jù)他們?cè)诒緦傩灾斜欢x的順序,第一個(gè)會(huì)被使用。
該spider也提供了一個(gè)可復(fù)寫(overrideable)的方法:
- parse_start_url(response)
當(dāng)start_url的請(qǐng)求返回時(shí),該方法被調(diào)用。 該方法分析最初的返回值并必須返回一個(gè) Item 對(duì)象或者 一個(gè) Request 對(duì)象或者 一個(gè)可迭代的包含二者對(duì)象。
爬取規(guī)則(Crawling rules)
class scrapy.contrib.spiders.Rule(link_extractor, callback=None, cb_kwargs=None, follow=None, process_links=None, process_request=None)- link_extractor:是一個(gè) Link Extractor 對(duì)象。 其定義了如何從爬取到的頁面提取鏈接。
- callback:是一個(gè)callable或string(該spider中同名的函數(shù)將會(huì)被調(diào)用)。 從link_extractor中每獲取到鏈接時(shí)將會(huì)調(diào)用該函數(shù)。該回調(diào)函數(shù)接受一個(gè)response作為其第一個(gè)參數(shù), 并返回一個(gè)包含 Item 以及(或) Request 對(duì)象(或者這兩者的子類)的列表(list)。
- cb_kwargs:包含傳遞給回調(diào)函數(shù)的參數(shù)(keyword argument)的字典。
- follow:是一個(gè)布爾(boolean)值,指定了根據(jù)該規(guī)則從response提取的鏈接是否需要跟進(jìn)。 如果 callback 為None, follow 默認(rèn)設(shè)置為 True ,否則默認(rèn)為 False 。
- process_links:是一個(gè)callable或string(該spider中同名的函數(shù)將會(huì)被調(diào)用)。 從link_extractor中獲取到鏈接列表時(shí)將會(huì)調(diào)用該函數(shù)。該方法主要用來過濾。
- process_request:是一個(gè)callable或string(該spider中同名的函數(shù)將會(huì)被調(diào)用)。 該規(guī)則提取到每個(gè)request時(shí)都會(huì)調(diào)用該函數(shù)。該函數(shù)必須返回一個(gè)request或者None。 (用來過濾request)
CrawlSpider樣例
import scrapy from scrapy.contrib.spiders import CrawlSpider, Rule from scrapy.contrib.linkextractors import LinkExtractorclass MySpider(CrawlSpider):name = 'example.com'allowed_domains = ['example.com']start_urls = ['http://www.example.com']rules = (# 提取匹配 'category.php' (但不匹配 'subsection.php') 的鏈接并跟進(jìn)鏈接(沒有callback意味著follow默認(rèn)為True)Rule(LinkExtractor(allow=('category\.php', ), deny=('subsection\.php', ))),# 提取匹配 'item.php' 的鏈接并使用spider的parse_item方法進(jìn)行分析Rule(LinkExtractor(allow=('item\.php', )), callback='parse_item'),)def parse_item(self, response):self.log('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的鏈接并對(duì)后者使用 parse_item 方法。 當(dāng)item獲得返回(response)時(shí),將使用XPath處理HTML并生成一些數(shù)據(jù)填入 Item 中。
先了解一下。。
https://scrapy-chs.readthedocs.io/zh_CN/latest/topics/spiders.html#scrapy.spider.Spider.allowed_domains
總結(jié)
以上是生活随笔為你收集整理的Python 爬虫框架Scrapy Spiders学习的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 杂文笔记(一):博弈论在网络安全中的应用
- 下一篇: 北京春运更智能:自助验票、微信查询