items.py:用来定义需要保存的变量,其中的变量用Field来定义,有点像python的字典
pipelines.py:用来将提取出来的Item进行处理,处理过程按自己需要进行定义
spiders:定义自己的爬虫
===========================================
1.测试示例爬虫
直接执行quotesbot示例工程spiders中爬虫toscrape-css
# -*- coding: utf-8 -*-
import scrapy
class ToScrapeCSSSpider(scrapy.Spider):
name = "toscrape-css"
start_urls = [
'http://quotes.toscrape.com/',
]
def parse(self, response):
for quote in response.css("div.quote"):
"""css选择器表示选择元素"""
yield {
'text': quote.css("span.text::text").extract_first(), #选择class="text"的span标签
'author': quote.css("small.author::text").extract_first(),
'tags': quote.css("div.tags > a.tag::text").extract() #选择class="tags"的<div>标签中,class="tags"的<a>子标签
}
next_page_url = response.css("li.next > a::attr(href)").extract_first()
if next_page_url is not None:
yield scrapy.Request(response.urljoin(next_page_url))
cd进入spiders目录后,敲入command:
scrapy runspider toscrape-css.py
执行toscrape-css爬虫
[执行结果]
... ...
2016-11-08 15:30:50 [scrapy] DEBUG: Scraped from <200 http://quotes.toscrape.com
/page/10/>
{'text': u'\u201c... a mind needs books as a sword needs a whetstone, if it is t
o keep its edge.\u201d', 'tags': [u'books', u'mind'], 'author': u'George R.R. Ma
rtin'}
2016-11-08 15:30:50 [scrapy] INFO: Closing spider (finished)
2016-11-08 15:30:50 [scrapy] INFO: Dumping Scrapy stats:
{'downloader/exception_count': 1,
'downloader/exception_type_count/twisted.internet.error.DNSLookupError': 1,
'downloader/request_bytes': 3086,
'downloader/request_count': 12,
'downloader/request_method_count/GET': 12,
'downloader/response_bytes': 24812,
'downloader/response_count': 11,
'downloader/response_status_count/200': 10,
'downloader/response_status_count/404': 1,
'finish_reason': 'finished',
'finish_time': datetime.datetime(2016, 11, 8, 7, 30, 50, 864000),
'item_scraped_count': 100,
'log_count/DEBUG': 113,
'log_count/INFO': 9,
'request_depth_max': 9,
'response_received_count': 11,
'scheduler/dequeued': 10,
'scheduler/dequeued/memory': 10,
'scheduler/enqueued': 10,
'scheduler/enqueued/memory': 10,
'start_time': datetime.datetime(2016, 11, 8, 7, 28, 42, 44000)}
2016-11-08 15:30:50 [scrapy] INFO: Spider closed (finished)
E:\PythonTest\quotesbot-scrapy\quotesbot\spiders>
2.爬虫Spider分析
class scrapy.spider.Spider
Spider是最简单的spider。每个其他的spider必须继承自该类(包括Scrapy自带的其他spider以及自己编写的spider)。
Spider并没有提供什么特殊的功能。
其仅仅请求给定的 start_urls/start_requests ,
并根据返回的结果(resulting responses)
调用spider的 parse 方法。
name
定义spider名字的字符串(string)。
spider的名字定义了Scrapy如何定位(并初始化)spider,所以其必须是唯一的。 不过可以生成多个相同的spider实例(instance),这没有任何限制。
name是spider最重要的属性,而且是必须的。
allowed_domains
可选。包含了spider允许爬取的域名(domain)列表(list)。
当 OffsiteMiddleware 启用时, 域名不在列表中的URL不会被跟进。
start_urls
URL列表。
当没有制定特定的URL时,spider将从该列表中开始进行爬取。
因此,第一个被获取到的页面的URL将是该列表之一。 后续的URL将会从获取到的数据中提取。
start_requests()
该方法必须返回一个可迭代对象(iterable)。
该对象包含了spider用于爬取的第一个Request。
当spider启动爬取并且未制定URL时,该方法被调用。
当指定了URL时,make_requests_from_url() 将被调用来创建Request对象。
该方法仅仅会被Scrapy调用一次,可以将其实现为生成器。
该方法的默认实现是使用 start_urls 的url生成Request。
如果想要修改最初爬取某个网站的Request对象,可以重写(override)该方法。
例如,如果需要在启动时以POST登录某个网站:
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参数也被设置为开启。
parse(response)
当response没有指定回调函数时,该方法是Scrapy处理下载的response的默认方法。
parse 负责处理response并返回处理的数据以及(/或)跟进的URL。
Spider 对其他的Request的回调函数也有相同的要求。
该方法及其他的Request回调函数必须返回一个包含 Request 及(或) Item 的可迭代的对象。
参数: response (Response) – 用于分析的response
log(message[, level, component])
使用 scrapy.log.msg() 方法记录(log)message。 log中自动带上该spider的 name 属性。
更多数据请参见 Logging
closed(reason)
当spider关闭时,该函数被调用。
该方法提供了一个替代调用signals.connect()来监听 spider_closed 信号的快捷方式。