参考:https://docs.scrapy.org/en/latest/topics/spiders.html
构架图:
就上上图中最上边那个SPIDERS,用来生成起始的REQUEST,解析返回的RESPONSE,从中提取数据并发阖家出去,另外从RESPONSE中解析出新的URL,然后生成request供中间的ENGINE调用。
scrapy.Spider
这个类是最简单最基本的SPIDER实现,其它复杂一点的SPIDER都要从它继承。
classscrapy.spiders.
Spider
name
SPIDER的名字,必需唯一,用于标识SPIDER的身份.需要注意的是用户可同时运行同一个SPIDER的多个实例.
allowed_domains
里边是一个字符串列表,基于域名对URI进行简单的过滤,需要启用offsiteMiddleware中间件,因为这个东西是真正实现过滤的地方.
start_urls
就是入口url.
custom_settings
这个是SPIDER级的配置,比项目级更细化一步,它是一个dict.具体可用的配置项参考这里.
crawler
此成员在当前SPIDER完成初始化由from_crawler方法初始化.crawler实例应该代表了事个Scrapy中的全部组件,通过crawler接口SPIDER可以访问整个系统中的任务组件应该是.
settings
这个也是设置,个人理解应该没有custom_settings优先级高.
详细参考这里.
logger
出日志的.
from_crawler
(crawler, *args, **kwargs)
Scrapy创建SPIDER的方法.
大多数情况下不需要覆盖.
其默认实现为__init__的代理,也就是默认实现其实什么都没干.
Parameters: |
---|
start_requests
()
在爬虫开启的时候被调用,只会被调用一次.它有默认实现.
改成登陆实现.
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
parse
(response)
解析response
Parameters: | response (Response ) – the response to parse |
---|
log
(message[, level, component])
输出日志
closed
(reason)
关闭SPIDER.
Generic Spiders
提供了一些scrapy.Spider的扩展实现类,在开发自己的应用时可以作为参考.
CrawlSpider
一个非常好的实现,它最大的特点就是"rule"的应用,这个规则定义了SPIDER爬取网页的策略.
关于这个Crawling rules类定义如下:
class scrapy.spiders.Rule(link_extractor, callback=None, cb_kwargs=None, follow=None, process_links=None, process_request=None)
link_extractor:定义如何从response中提取新链接,并用提取到的链接生成新的REQUEST.
callback:为新生成的REQUEST指定回调处理方法.
cb_kwargs:一个传递给callback的dict.
follow:是否follow新提取出来的link.默认情况下,如果callback是None则它是True,否则是False.follow的意思就像浏览网页一样,对于网页上出现的一个链接,如果占进去看了,就是follow,如果没点进去,就不是follow.
process_links:link_extractor提取出来的link要先经过它处理.
process_reuqest:用来处理request的地方.
CrawlSpider example
import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
class 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()').get()
item['description'] = response.xpath('//td[@id="item_description"]/text()').get()
item['link_text'] = response.meta['link_text']
return item