通过下面的命令可以快速创建 CrawlSpider模板 的代码:
scrapy genspider -t crawl tencent tencent.com
上一个案例中,我们通过正则表达式,制作了新的url作为Request请求参数,现在我们可以换个花样...
class scrapy.spiders.CrawlSpider
它是Spider的派生类,Spider类的设计原则是只爬取start_url列表中的网页,而CrawlSpider类定义了一些规则(rule)来提供跟进link的方便的机制,从爬取的网页中获取link并继续爬取的工作更适合。
- class CrawlSpider(Spider):
- rules = ()
- def __init__(self, *a, **kw):
- super(CrawlSpider, self).__init__(*a, **kw)
- self._compile_rules()
-
- #首先调用parse()来处理start_urls中返回的response对象
- #parse()则将这些response对象传递给了_parse_response()函数处理,并设置回调函数为parse_start_url()
- #设置了跟进标志位True
- #parse将返回item和跟进了的Request对象
- def parse(self, response):
- return self._parse_response(response, self.parse_start_url, cb_kwargs={}, follow=True)
-
- #处理start_url中返回的response,需要重写
- def parse_start_url(self, response):
- return []
-
- def process_results(self, response, results):
- return results
-
- #从response中抽取符合任一用户定义'规则'的链接,并构造成Resquest对象返回
- def _requests_to_follow(self, response):
- if not isinstance(response, HtmlResponse):
- return
- seen = set()
- #抽取之内的所有链接,只要通过任意一个'规则',即表示合法
- for n, rule in enumerate(self._rules):
- links = [l for l in rule.link_extractor.extract_links(response) if l not in seen]
- #使用用户指定的process_links处理每个连接
- if links and rule.process_links:
- links = rule.process_links(links)
- #将链接加入seen集合,为每个链接生成Request对象,并设置回调函数为_repsonse_downloaded()
- for link in links:
- seen.add(link)
- #构造Request对象,并将Rule规则中定义的回调函数作为这个Request对象的回调函数
- r = Request(url=link.url, callback=self._response_downloaded)
- r.meta.update(rule=n, link_text=link.text)
- #对每个Request调用process_request()函数。该函数默认为indentify,即不做任何处理,直接返回该Request.
- yield rule.process_request(r)
-
- #处理通过rule提取出的连接,并返回item以及request
- def _response_downloaded(self, response):