爬虫入门15Scrapy基本概念介绍—命令行参数和Spider
Posted 一步一步学Python
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了爬虫入门15Scrapy基本概念介绍—命令行参数和Spider相关的知识,希望对你有一定的参考价值。
创建一个scrapy项目
首先我们要做的就是创建一个项目,基本的命令如下:
scrapy startproject myproject [project_dir]
如果指定了project_dir,那么就会在该目录下创建一个project。
如果没有指定project_dir时,会在当前命令行目录下创建项目。
然后我们就可以在项目根目录下进行一系列操作了。
推荐创建scrapy项目后,使用pycharm来管理,写代码或者命令行操作都要简单很多。
可用的命令工具
可以通过scrapy
也可以使用scrapy -h来获取所有的可用命令。
全局命令:
startproject
genspider
settings
runspider
shell
fetch
view
version
Porject-only命令
crawl
check
list
edit
parse
bench
每个命令的用法
startproject
上面讲过了,用于创建一个项目。
genspider
基本命令格式如下:
scrapy genspider [-t template] <name> <domain>
在当前目录下创建一个spider文件;
或者在当前项目的spider文件夹中,如果是在项目命令行中使用的话。
简单举个例子:
$ scrapy genspider -l
Available templates:
basic
crawl
csvfeed
xmlfeed
$ scrapy genspider example example.com
Created spider 'example' using template 'basic'
$ scrapy genspider -t crawl scrapyorg scrapy.org
Created spider 'scrapyorg' using template 'crawl'
我更倾向于自己创建spider文件,而不是使用命令行。
crawl
基本命令格式:
scrapy crawl <spider>
用于启动爬取,指定spider。
$ scrapy crawl myspider
[ ... myspider starts crawling ... ]
check
scrapy check [-1] <spider>
运行契约检查。
$ scrapy check -l
first_spider
* parse
* parse_item
second_spider
* parse
* parse_item
list
用于列举出所有可用的spider。
这里的spider指的是我们定义的爬虫,如果设置了name属性,那就会显示name来。
fetch
scrapy fetch [OPTION] <url>
通过Scrapy下载指定的url,然后私用标准输出格式写出来。
举个例子先:
$ scrapy fetch --nolog http://www.example.com/some/page.html
[ ... html content here ... ]
$ scrapy fetch --nolog --headers http://www.example.com/
{'Accept-Ranges': ['bytes'], 'Age': ['1263 '], 'Connection': ['close '], 'Content-Length': ['596'], 'Content-Type': ['text/html; charset=UTF-8'], 'Date': ['Wed, 18 Aug 2010 23:59:46 GMT'], 'Etag': ['"573c1-254-48c9c87349680"'], 'Last-Modified': ['Fri, 30 Jul 2010 15:30:18 GMT'], 'Server': ['Apache/2.2.3 (CentOS)']}
Spiders
我们讲一个spider,其实就是一个类,这个类描述了如何爬取一个页面,包括如何运行爬取命令,如何解析页面的数据。
创建一个spider就是创建一个继承scrapy.Spider的类,在这个类中定义一些属性和函数。
下面我们来讲一下这个类的成员。
scrapy.Spider
每个spider都要继承这个类。
该类没有提供特殊的功能。只是提供了一个默认的start_requests()实现,从start_urls属性发送请求,然后调用spider的parse方法,来处理每个response。
name
用于定义spider的名称,调用时直接使用name属性即可。
allowed_domains
start_urls
爬取的目标网址组成的list。
crawler
这个属性通过from_crawler()类方法来设置,与Crawler对象链接。
from_crawler(crawler, args, *kwargs)
Scrapy使用这个方法来创建spider。
无需直接重写这个方法,其优先级要高于init()方法。
start_requests()
这个方法返回一个迭代器,第一次使用这个spider来爬取的请求。
Scrapy只会调用一次该方法,所以将该方法实现为一个生成器是很安全的。
默认的实现,生成Request(url,dont_filter=True),针对start_urls中的每个url。
如果想要改变用于开始爬取域名的请求,我们可以重写这个方法。
举个例子,如果我们想通过POST请求登陆一个页面,可以这么写:
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。
parse方法负责分析response,返回爬取的数据和更多要follow的URL。
上面解读了一些spider类中常用的方法,我们再来看一个例子:
import scrapyclass MySpider(scrapy.Spider):
name = 'example.com'
allowed_domains = ['example.com']
start_urls = [ 'http://www.example.com/1.html', 'http://www.example.com/2.html', 'http://www.example.com/3.html',
]
def parse(self, response):
self.logger.info('A response from %s just arrived!', response.url)
从一个单一请求,返回多重Requests和item。
举个例子:
import scrapyclass MySpider(scrapy.Spider):
name = 'example.com'
allowed_domains = ['example.com']
start_urls = [ 'http://www.example.com/1.html', 'http://www.example.com/2.html', 'http://www.example.com/3.html',
]
def parse(self, response):
for h3 in response.xpath('//h3').extract(): yield {"title": h3} for url in response.xpath('//a/@href').extract(): yield scrapy.Request(url, callback=self.parse)
如果不使用start_urls,我们可以使用start_requests(),我们可以使用Items,设置data有更多的结构。
import scrapyfrom myproject.items import MyItem
class MySpider(scrapy.Spider):
name = 'example.com'
allowed_domains = ['example.com']
def start_requests(self):
yield scrapy.Request('http://www.example.com/1.html', self.parse)
yield scrapy.Request('http://www.example.com/2.html', self.
yield scrapy.Request('http://www.example.com/3.html', self.
def parse(self, response):
for h3 in response.xpath('//h3').extract():
yield MyItem(title=h3)
for url in response.xpath('//a/@href').extract():
yield scrapy.Request(url, callback=self.parse)
Spider参数
spider能够接受参数,用来修改spider的行为。一些常见的用法是用来定义起点的url,或者限定爬取网页的特定部分。
spider参数都使用-a选项来传递crawl命令,举个例子:
scrapy crawl myspider -a category=electronics
spider能够在init方法中获取参数。举例:
import scrapyclass MySpider(scrapy.Spider):
name = 'myspider'
def __init__(self, category=None, *args, **kwargs):
super(MySpider, self).__init__(*args, **kwargs)
self.start_urls = ['http://www.example.com/categories/%s' % category] # ...
init方法会将任何一个参数赋值为spider的属性。上面的例子可以写成如下这种:
import scrapyclass MySpider(scrapy.Spider):
name = 'myspider'
def start_requests(self):
yield scrapy.Request('http://www.example.com/categories/%s' % self.category)
请务必牢记spider的参数一定是字符串。
如果想要从命令行设置start_urls属性,那就要自行将其转换成一个list,可可以使用json.loads,然后设置其为属性。
Generic Spiders
Scrapy提供了一些有用的普通spider,让我们来扩展。目的是提供一些便利的功能,基于特定的规则。
假设我们已经声明了一个TestItem类,在myproject.items模块中定义:
import scrapyclass TestItem(scrapy.Item):
id = scrapy.Field()
name = scrapy.Field()
description = scrapy.Field()
CrawlSpider
这是经常用来爬取常规页面的spider,它提供了一个方便的机制,设置了一系列规则。
也许它不是最合适的spider,但是适用普通的案例。我们可以从这个spider开始,然后重写它,或者直接实现你需要的功能。
import scrapyfrom scrapy.spiders import CrawlSpider, Rulefrom scrapy.linkextractors import LinkExtractorclass 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()').extract()
item['description'] = response.xpath('//td[@id="item_description"]/text()').extract() return item
以上是关于爬虫入门15Scrapy基本概念介绍—命令行参数和Spider的主要内容,如果未能解决你的问题,请参考以下文章
Python爬虫从入门到放弃(十三)之 Scrapy框架的命令行详解
Python网络爬虫实战-Scrapy视频教程 Python系统化项目实战课程 Scrapy技术课程
Python爬虫从入门到成妖之3-----Scrapy框架的命令行详解