Scrapy 简明教程
Scrapy - Spiders
scrapy.Spider
它是一个爬虫,每个其他爬虫都必须从中继承。它具有以下类 −
class scrapy.spiders.Spider
下表显示了 scrapy.Spider 类的字段 −
Sr.No |
Field & Description |
1 |
name 它是爬虫的名称。 |
2 |
allowed_domains 它是爬虫抓取的域的列表。 |
3 |
start_urls 它是 URL 的列表,它们将成为以后抓取的根源,爬虫将从中开始抓取。 |
4 |
custom_settings 这些是设置,在运行爬虫时,将从项目范围配置中覆盖。 |
5 |
crawler 它是一个属性,链接到 spider 实例所绑定的 Crawler 对象。 |
6 |
settings 这些是用于运行爬虫的设置。 |
7 |
logger 它是一个 Python 日志记录器,用于发送日志消息。 |
8 |
from_crawler(crawler,*args, kwargs)*它是一个类方法,用于创建爬虫。参数是 − *crawler − 爬虫实例将与其绑定的爬取器。 args(list) − 这些参数传递给 init () 方法。 kwargs(dict) − 这些关键字参数传递给 init () 方法。 |
9 |
start_requests() 如果未指定特定的 URL 并且针对爬取打开了蜘蛛,则 Scrapy 会调用 start_requests() 方法。 |
10 |
make_requests_from_url(url) 这是一个用于将 url 转换为请求的方法。 |
11 |
parse(response) 此方法处理响应并返回废弃数据,并遵循更多 URL。 |
12 |
log(message[,level,component]) 这是一个通过 Spider 记录器发送日志消息的方法。 |
13 |
closed(reason) 此方法在 Spider 关闭时调用。 |
Spider Arguments
Spider 参数用于指定开始 URL,并使用 crawl 命令与 -a 选项一起传递,如下所示 −
scrapy crawl first_scrapy -a group = accessories
以下代码演示了 Spider 如何接收参数 −
import scrapy
class FirstSpider(scrapy.Spider):
name = "first"
def __init__(self, group = None, *args, **kwargs):
super(FirstSpider, self).__init__(*args, **kwargs)
self.start_urls = ["http://www.example.com/group/%s" % group]
Generic Spiders
你可以使用通用 Spider 对你的 Spider 进行子类化。它们的目的是根据特定规则遵循网站上的所有链接,以便从所有页面中提取数据。
对于以下 Spider 中使用的示例,让我们假设我们有一个包含以下字段的项目 −
import scrapy
from scrapy.item import Item, Field
class First_scrapyItem(scrapy.Item):
product_title = Field()
product_link = Field()
product_description = Field()
CrawlSpider
CrawlSpider 定义了一组要遵循的规则,以便遵循链接并提取多个页面。它具有以下类 −
class scrapy.spiders.CrawlSpider
下面是 CrawlSpider 类的属性 −
rules
这是一个规则对象的列表,它定义了爬虫如何遵循链接。
下表显示了 CrawlSpider 类的规则 −
Sr.No |
Rule & Description |
1 |
LinkExtractor 它指定了 Spider 如何遵循链接并提取数据。 |
2 |
callback 它应该在每个页面被废弃之后调用。 |
3 |
follow 它指定是否继续遵循链接。 |
parse_start_url(response)
它可以通过允许解析初始响应来返回项目或请求对象。
Note − 确保在编写规则时,将 parse 函数重命名为除 parse 之外的其他名称,因为 parse 函数由 CrawlSpider 用于实现其逻辑。
让我们看一看以下示例,其中 Spider 开始爬取 demoexample.com 的主页,收集所有页面、链接,并使用 parse_items 方法进行解析 −
import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
class DemoSpider(CrawlSpider):
name = "demo"
allowed_domains = ["www.demoexample.com"]
start_urls = ["http://www.demoexample.com"]
rules = (
Rule(LinkExtractor(allow =(), restrict_xpaths = ("//div[@class = 'next']",)),
callback = "parse_item", follow = True),
)
def parse_item(self, response):
item = DemoItem()
item["product_title"] = response.xpath("a/text()").extract()
item["product_link"] = response.xpath("a/@href").extract()
item["product_description"] = response.xpath("div[@class = 'desc']/text()").extract()
return items
XMLFeedSpider
它是从 XML feed 进行抓取并迭代节点的爬虫的基础类。它有以下类:
class scrapy.spiders.XMLFeedSpider
下表显示用于设置迭代器和标签名的类属性:
Sr.No |
Attribute & Description |
1 |
iterator 它定义了要使用的迭代器。它可以是 iternodes、html 或 xml。默认值为 iternodes。 |
2 |
itertag 它是一个用于迭代的节点名称字符串。 |
3 |
namespaces 它由 (prefix, uri) 元组列表定义,该列表使用 register_namespace() 方法自动注册命名空间。 |
4 |
adapt_response(response) 当来自爬虫中间件的响应到达时,它接收响应并修改响应正文,在爬虫开始解析它之前。 |
5 |
parse_node(response,selector) 当调用每个与提供标签名称匹配的节点时,它接收响应和一个选择器。 Note -如果你不重写该方法,你的爬虫将不起作用。 |
6 |
process_results(response,results) 返回爬虫返回的结果和响应列表。 |
CSVFeedSpider
它遍历每行,接收 CSV 文件作为响应,并调用 parse_row() 方法。它有以下类:
class scrapy.spiders.CSVFeedSpider
下表显示了关于 CSV 文件的设置选项:
Sr.No |
Option & Description |
1 |
delimiter 它是一个包含逗号(“,”)分隔符的字符串,用于每个字段。 |
2 |
quotechar 它是一个包含引号(“"”)的字符串,用于每个字段。 |
3 |
headers 它是一个包含字段可以从中提取的语句的列表。 |
4 |
parse_row(response,row) 它接收响应和每一行以及头部的键。 |
CSVFeedSpider Example
from scrapy.spiders import CSVFeedSpider
from demoproject.items import DemoItem
class DemoSpider(CSVFeedSpider):
name = "demo"
allowed_domains = ["www.demoexample.com"]
start_urls = ["http://www.demoexample.com/feed.csv"]
delimiter = ";"
quotechar = "'"
headers = ["product_title", "product_link", "product_description"]
def parse_row(self, response, row):
self.logger.info("This is row: %r", row)
item = DemoItem()
item["product_title"] = row["product_title"]
item["product_link"] = row["product_link"]
item["product_description"] = row["product_description"]
return item
SitemapSpider
SitemapSpider 在 Sitemaps 的帮助下,通过从 robots.txt 中查找 URL 来抓取网站。它有以下类:
class scrapy.spiders.SitemapSpider
下表显示了 SitemapSpider 的字段:
Sr.No |
Field & Description |
1 |
sitemap_urls 要抓取指向网站地图的 URL 列表。 |
2 |
sitemap_rules 元组 (regex, callback)的列表,其中 regex 是正则表达式,而 callback 用于处理匹配正则表达式的 URL。 |
3 |
sitemap_follow 要遵循的网站地图正则表达式列表。 |
4 |
sitemap_alternate_links 指定要为单一网址遵循的备用链接。 |
SitemapSpider Example
以下 SitemapSpider 处理所有 URL −
from scrapy.spiders import SitemapSpider
class DemoSpider(SitemapSpider):
urls = ["http://www.demoexample.com/sitemap.xml"]
def parse(self, response):
# You can scrap items here
以下 SitemapSpider 使用回调处理一些 URL −
from scrapy.spiders import SitemapSpider
class DemoSpider(SitemapSpider):
urls = ["http://www.demoexample.com/sitemap.xml"]
rules = [
("/item/", "parse_item"),
("/group/", "parse_group"),
]
def parse_item(self, response):
# you can scrap item here
def parse_group(self, response):
# you can scrap group here
以下代码显示 robots.txt 中网址为 /sitemap_company 的 sitemap。
from scrapy.spiders import SitemapSpider
class DemoSpider(SitemapSpider):
urls = ["http://www.demoexample.com/robots.txt"]
rules = [
("/company/", "parse_company"),
]
sitemap_follow = ["/sitemap_company"]
def parse_company(self, response):
# you can scrap company here
您甚至可以将 SitemapSpider 与其他 URL 结合使用,如下面的命令所示。
from scrapy.spiders import SitemapSpider
class DemoSpider(SitemapSpider):
urls = ["http://www.demoexample.com/robots.txt"]
rules = [
("/company/", "parse_company"),
]
other_urls = ["http://www.demoexample.com/contact-us"]
def start_requests(self):
requests = list(super(DemoSpider, self).start_requests())
requests += [scrapy.Request(x, self.parse_other) for x in self.other_urls]
return requests
def parse_company(self, response):
# you can scrap company here...
def parse_other(self, response):
# you can scrap other here...