Scrapy学习二:基本概念进阶(未完成)
来源:互联网 发布:达梦数据库安装教程 编辑:程序博客网 时间:2024/06/03 20:34
基本概念详述
原始文档链接:https://docs.scrapy.org/en/latest/#basic-concepts 以及其中的后续链接。
前置链接:Scrapy学习一
- Command line tool —— 命令行工具
管理Scrapy项目的工具 - Spiders —— 爬虫
这个不用解释了吧 - Selectors —— 选择器
使用CSS or XPath从网页提取数据 - Scrapy shell
测试提取代码的可交互shell - Items
定义爬取的数据 - Item Loaders —— Item装载器
用提取的数据构成Item - Item Pipeline
后续处理,以及存储爬获的数据。小型项目中留空 - Feed exports
使用预定义的多种格式或存储输出爬获的数据 - Requests and Responses —— 请求和响应
了解HTTP request和response报文中的class - Link Extractors —— 链接提取器
处理后续链接的实用类 - Settings —— 设置
学习如何配置Scrapy可选项 - Exceptions —— 异常处理
理解所有可用异常代码的意义
一、命令行工具
自0.10版中出现了命令行工具以后,Scrapy也可以由 scrapy 命令行命令控制进行工作。
注:有如下术语:command-line tool(命令行工具), Scrapy tool(Scrapy工具)都表达同一意思;但区别于术语:sub-commands(子命令),commands(命令),Scrapy commands(Scrapy命令)。
Scrapy工具提供了许多实用命令,有些命令针对多目标,有些针对每个目标可设置不同参数和选项集。
注:scrapy deploy 命令在1.0版本中被移除,以更好的支持 scrapyd-deploy 命令。详见:如何部署你的项目
1.1 配置设置
Scrapy所有参数配置在文件 scrapy.cfg 中。文件位置可以是:
1. /etc/scrapy.cfg 或 c:\scrapy\scrapy.cfg 作为系统级全局配置2. ~/.config/scrapy.cfg ($XDG_CONFIG_HOME) 或 ~/.scrapy.cfg ($HOME) 作为用户级全局配置,3. 在一个Scrapy项目中,作为项目级配置
配置文件的优先级为:项目级配置 覆盖 用户级配置 覆盖 系统级配置。
Scrapy还有一些环境变量,如:
- SCRAPY_SETTINGS_MODULE
- SCRAPY_PROJECT
- SCRAPY_PYTHON_SHELL
1.2 Scrapy默认项目结构
在深入命令行工具之前,我们有必要先了解一下一个Scrapy项目的目录结构:
scrapy.cfgmyproject/ __init__.py items.py pipelines.py settings.py spiders/ __init__.py spider1.py spider2.py ...
可以看到,scrapy.cfg 在项目根目录,spiders/目录下可以并存多个spider。
回到 scrapy.cfg ,在之前的学习中我们建立过一个 tutorial 项目,它的配置文档是这样的:
# Automatically created by: scrapy startproject## For more information about the [deploy] section see:# https://scrapyd.readthedocs.org/en/latest/deploy.html[settings]default = tutorial.settings[deploy]#url = http://localhost:6800/project = tutorial
我们可以看到,这是由 scrapy startproject 命令创建的配置文档,另一种创建配置文档的途径是 deploy (部署)。
1.3 使用 Scrapy 工具
我们尝试着运行一下 Scrapy 工具,如果不带正确的参数,并且不在一个项目内,会返回默认的帮助:
C:\ 项目外 > ScrapyScrapy 1.2.1 - no active projectUsage: scrapy <command> [options] [args]Available commands: bench Run quick benchmark test commands fetch Fetch a URL using the Scrapy downloader genspider Generate new spider using pre-defined templates runspider Run a self-contained spider (without creating a project) settings Get settings values shell Interactive scraping console startproject Create new project version Print Scrapy version view Open URL in browser, as seen by Scrapy [ more ] More commands available when run from project directoryUse "scrapy <command> -h" to see more info about a command
当进入项目,运行命令 scrapy :
C:\tutorial> scrapyScrapy 1.2.1 - project: tutorial
会自动识别出项目。当然没有带正确的参数以前,返回的仍旧是一个默认的帮助页。
1.4 创建项目
我们之前已经学习过如何创建项目。但更通常地:
scrapy startproject myproject [project_dir]
项目由上述命令创建,项目名称为 myproject,项目位置为 project_dir 。当然如果不指定项目位置,默认就是项目当前位置。
1.5 控制项目
我们进入项目文件夹
cd project_dir
开始学习在项目内使用scrapy工具。
首先,你可以使用如下命令创建一个 spider:
scrapy genspider mydomain mydomain.com
之前提到过,一些命令必须在项目内部执行(例如:crawl);而 genspider 是全局命令。
注:关于Scrapy命令是项目内的还是全局的,可以参考:https://docs.scrapy.org/en/latest/topics/commands.html#topics-commands-ref
有些命令在项目内外运行时结果是不一样的。例如: fetch 命令,如果抓取的url指定了 spider,那么项目内的 spider 将被覆盖。(就像 user_agent 属性会覆盖 user-agent)。这样的覆盖是故意的,目的是为了使用 fetch 命令时能够获悉 spider 如何下载网页。
1.6 可用的命令
我们总是可以使用帮助命令:
scrapy -h
来查看所有可用命令。并使用:
scrapy <COMMAND> -h
来获得更详细的命令帮助信息。
如之前所说,命令分项目内的 Project-only commands 和项目外的 Global commands:
Global commands:
startprojectgenspidersettingsrunspidershellfetchviewversion
Project-only commands:
crawlchecklisteditparsebench
接下来将详细叙述它们。
1.6.1 startproject
- 语法:
scrapy startproject <project_name> [project_dir]
- 基于项目:否
- 用途:创建一个新的Scrapy项目,以 project_name 命名,目录为 project_dir 。如果不指定 project_dir,默认以 project_name 创建目录。
- 示例:
$ scrapy startproject myproject
1.6.2 genspider
- 语法:
scrapy genspider [-t template] <name> <domain>
- 基于项目:否
- 用途:创建一个新的spider。位置为(项目外)当前文件夹或(项目内)当前项目的 spiders/ 目录下。参数讲被传入 class 下的name属性,参数用来生成 allowed_domains 以及 start_urls。
- 示例:
列举可用spider模板:
$ scrapy genspider -lAvailable templates: basic crawl csvfeed xmlfeed
使用默认模板basic创建名为example的spider:
$ scrapy genspider example example.com
使用模板crawl创建名为scrapyorg的spider,域限定 scrapy.org
$ scrapy genspider -t crawl scrapyorg scrapy.org
这些只是使用预定义模板创建spider的快捷命令,你也可以自己创建并修改xxxspider.py源文件。
1.6.3 crawl
- 语法: scrapy crawl
- 基于项目:yes
- 用途:在项目中启动一个spider
- 示例:
$ scrapy crawl myspider
1.6.4 check
- 语法: scrapy check [-l]
- 基于项目:是
- 用途:检查spiders py代码。如错误会详述错误,如正确则没有返回输出。
- 示例:
$ scrapy check -lfirst_spider * parse * parse_itemsecond_spider * parse * parse_item
$ scrapy check[FAILED] first_spider:parse_item>>> 'RetailPricex' field is missing[FAILED] first_spider:parse>>> Returned 92 requests, expected 0..4
1.6.5 list
- 语法: scrapy list
- 基于项目:yes
- 用途:列述当前项目种所有可用的spider。
- 示例:
$ scrapy listspider1spider2
1.6.6 edit
- 语法: scrapy edit
- 基于项目:yes
- 用途:编辑名为的spider。没人会用这个功能,你大可在自己的Python IDE中编辑代码。
- 示例:
$ scrapy edit spider1
1.6.7 fetch
- 语法: scrapy fetch
- 基于项目:否
- 用途:用 Scrapy downloader 下载指定的 ,把输出写到 standard output。
这个命令有趣的地方是它会以spider中定义的方式获取目标url。例如如果spider中定义了 USER_AGENT 属性,那么这个命令会使用它来覆盖默认配置中的 User Agent。所以使用这条命令就能真是地看到spider所获取的页面。
同时注意到fetch命令是项目无关的,这表示如果在项目外输入了fetch命令,它也能获取页面,但只会使用默认的Scrapy下载器设定。
- 支持的选项:
--spider=SPIDER: 强制使用指定的spider,忽略spider自动检测--headers: 显示响应的 HTTP header 而不是 body--no-redirect: 禁止 HTTP 3xx 重定向自动跳转 (默认为自动跳转)--nolog: 无日志
- 示例:
$ scrapy fetch --nolog http://www.example.com/some/page.html[ ... html 内容 ... ]$ 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)']}
1.6.8 view
- 语法: scrapy view
- 基于项目:否
- 用途:在浏览器中打开指定的URL,页面为spider“看到”的响应内容。由于有时spider“看到”的会跟你直接在真实的浏览器中看到的不一样,这个命令对于查看这之间的区别非常有用。
- 支持的选项:
--spider=SPIDER: 强制使用指定的spider,忽略spider自动检测--no-redirect: 禁止 HTTP 3xx 重定向自动跳转 (默认为自动跳转)
- 示例:
$ scrapy view http://www.example.com/some/page.html[ ... browser starts ... ]
1.6.9 shell
- 语法: scrapy shell [url]
- 基于项目:否
- 用途:打开一个Scrapy shell,如果指定了URL,则基于此URL;否则打开一个空的shell。同时shell也支持打开本地文件,格式如类UNIX系统的相对路径 ./ or ../ 或直接使用绝对路径。
- 支持的选项:
--spider=SPIDER: 强制使用指定的spider,忽略spider自动检测-c code: 在shell中对 code 求值, 显示结果并退出。code 形如'(response.status, response.url)'--no-redirect: 禁止 HTTP 3xx 重定向自动跳转 (默认为自动跳转)
- 示例:
$ scrapy shell http://www.example.com/some/page.html[ ... scrapy shell starts ... ]$ scrapy shell --nolog http://www.example.com/ -c '(response.status, response.url)'(200, 'http://www.example.com/')# shell follows HTTP redirects by default$ scrapy shell --nolog http://httpbin.org/redirect-to?url=http%3A%2F%2Fexample.com%2F -c '(response.status, response.url)'(200, 'http://example.com/')# you can disable this with --no-redirect# (only for the URL passed as command line argument)$ scrapy shell --no-redirect --nolog http://httpbin.org/redirect-to?url=http%3A%2F%2Fexample.com%2F -c '(response.status, response.url)'(302, 'http://httpbin.org/redirect-to?url=http%3A%2F%2Fexample.com%2F')
1.6.10 parse
- 语法: scrapy parse [options]
- 基于项目:是
用途:默认为使用项目中spider内的parse()函数处理给的的URL,或使用 –callback 选项指定回调函数来提取数据。
Fetches the given URL and parses it with the spider that handles it, using the method passed with the –callback option, or parse if not given.Supported options:
--spider=SPIDER: bypass spider autodetection and force use of specific spider--a NAME=VALUE: set spider argument (may be repeated)--callback or -c: spider method to use as callback for parsing the response--pipelines: process items through pipelines--rules or -r: use CrawlSpider rules to discover the callback (i.e. spider method) to use for parsing the response--noitems: don’t show scraped items--nolinks: don’t show extracted links--nocolour: avoid using pygments to colorize the output--depth or -d: depth level for which the requests should be followed recursively (default: 1)--verbose or -v: display information for each depth level
- 示例:
$ scrapy parse http://www.example.com/ -c parse_item[ ... scrapy log lines crawling example.com spider ... ]>>> STATUS DEPTH LEVEL 1 <<<# Scraped Items ------------------------------------------------------------[{'name': u'Example item', 'category': u'Furniture', 'length': u'12 cm'}]# Requests -----------------------------------------------------------------[]
1.6.11 settings
- 语法: scrapy settings [options]
- 基于项目:否
用途:获取Scrapy设置。人工查看配置文件时一般不使用这个方法。在项目外显示全局配置,在项目内显示项目配置。
示例:
$ scrapy settings --get BOT_NAMEscrapybot$ scrapy settings --get DOWNLOAD_DELAY0
更多帮助参考:scrapy settings -h
1.6.12 runspider
- 语法: scrapy runspider
1.6.13 version
- 语法: scrapy version [-v]
- 基于项目:no
- 用途:显示Scrapy版本号。和 -v 一起用时会同时打印其他相关版本号如 Python, Twisted,lxml,libxml2,pyOpenSSL等等。
1.6.14 bench
New in version 0.17.
- 语法: scrapy bench
- 基于项目:否
- 用途:运行benchmark。
三、选择器
爬取网页后,通常你还需要从HTML源文件中提取有用数据。我们有很多库可以用:
- BeautifulSoup
- lxml
(这个就不翻了)
Scrapy有其独特的数据提取机制,因为它“选择”HTML文档中的某些部分所以称它为选择器。通常HTML可表述为 XPath 或 CSS 格式:
- XPath
- CSS
(这个也不翻了)
Scrapy 选择器基于lxml库,所以它们的数据提取速度和精度是十分相近的。
本章将阐述选择器如何工作并详述API。虽然Scrapy选择器基于lxml库,但Scrapy旨在数据提取,而抛弃了lxml中不相干的功能,所以其API短小精悍。
完整的选择器API参考链接:https://docs.scrapy.org/en/latest/topics/selectors.html#topics-selectors-ref
3.1 构造选择器
Scrapy选择器是实例化的 Selector 类,输入为 text 或 TextResponse 对象。根据不同的输入对象(HTML或XML),选择器会自动选择提取规则,无需手动指定:
>>> from scrapy.selector import Selector>>> from scrapy.http import HtmlResponse
输入为文本:
>>> body = '<html><body><span>good</span></body></html>'>>> Selector(text=body).xpath('//span/text()').extract()[u'good']
输入为HTML响应:
>>> response = HtmlResponse(url='http://example.com', body=body)>>> Selector(response=response).xpath('//span/text()').extract()[u'good']
简单起见,可以使用 response 对象的 .selector 属性,方式如下:
>>> response.selector.xpath('//span/text()').extract()[u'good']
3.2 使用选择器
我们使用 Scrapy shell 来阐述如何使用选择器这一问题。Scrapy shell 在之前我们已初步涉及,更详细地教程在本文的下一章。
本小节要使用的示例在:https://doc.scrapy.org/en/latest/_static/selectors-sample1.html
直接在浏览器中使用如下代码来查看其HTML源代码:
view-source:https://doc.scrapy.org/en/latest/_static/selectors-sample1.html
HTML源代码如下:
<html> <head> <base href='http://example.com/' /> <title>Example website</title> </head> <body> <div id='images'> <a href='image1.html'>Name: My image 1 <br /><img src='image1_thumb.jpg' /></a> <a href='image2.html'>Name: My image 2 <br /><img src='image2_thumb.jpg' /></a> <a href='image3.html'>Name: My image 3 <br /><img src='image3_thumb.jpg' /></a> <a href='image4.html'>Name: My image 4 <br /><img src='image4_thumb.jpg' /></a> <a href='image5.html'>Name: My image 5 <br /><img src='image5_thumb.jpg' /></a> </div> </body></html>
首先,在cmd中打开Scrapy shell:
scrapy shell http://doc.scrapy.org/en/latest/_static/selectors-sample1.html
等待shell装载完成,你会得到 response shell变量和对应的 response.selector 属性。由于我们处理的是HTML,选择器会自动使用HTML解析数据。
我们来看一下HTML代码,然后构建一个 XPath 来选择 title tag中的文字:
>>> response.selector.xpath('//title/text()')[<Selector (text) xpath=//title/text()>]
由于 XPath和CSS十分常用,所以 response 定义了更简便的方法: response.xpath() 和 response.css() :
>>> response.xpath('//title/text()')[<Selector (text) xpath=//title/text()>]>>> response.css('title::text')[<Selector (text) xpath=//title/text()>]
跟前面一样,这两个简便方法也返回一个 SelectorList 实例:一个list结构的新 selector。
接下来我们通过这个API来提取内嵌img图像的数据:
>>> response.css('img').xpath('@src').extract()[u'image1_thumb.jpg', u'image2_thumb.jpg', u'image3_thumb.jpg', u'image4_thumb.jpg', u'image5_thumb.jpg']
如果是要提取文字型数据,必须使用如下:
>>> response.xpath('//title/text()').extract()[u'Example website']
如果只想提取第一个符合的数据,使用基础教程中提到过的 .extract_first() 。
>>> response.xpath('//div[@id="images"]/a/text()').extract_first()u'Name: My image 1 '
当没有查询结果时返回None:
>>> response.xpath('//div[@id="not-exists"]/text()').extract_first() is NoneTrue
此外,当没有查询结果时,我们可以修改参数使默认的None改成我们需要的其他值,如 ‘not-found’:
>>> response.xpath('//div[@id="not-exists"]/text()').extract_first(default='not-found')'not-found'
现在我们分别用xpath和css提取示例中的所有URL和图片链接:
>>> response.xpath('//base/@href').extract()[u'http://example.com/']>>> response.css('base::attr(href)').extract()[u'http://example.com/']>>> response.xpath('//a[contains(@href, "image")]/@href').extract()[u'image1.html', u'image2.html', u'image3.html', u'image4.html', u'image5.html']>>> response.css('a[href*=image]::attr(href)').extract()[u'image1.html', u'image2.html', u'image3.html', u'image4.html', u'image5.html']>>> response.xpath('//a[contains(@href, "image")]/img/@src').extract()[u'image1_thumb.jpg', u'image2_thumb.jpg', u'image3_thumb.jpg', u'image4_thumb.jpg', u'image5_thumb.jpg']>>> response.css('a[href*=image] img::attr(src)').extract()[u'image1_thumb.jpg', u'image2_thumb.jpg', u'image3_thumb.jpg', u'image4_thumb.jpg', u'image5_thumb.jpg']
3.3 selector嵌套
无论是 .xpath() 还是 .css() 方法,都返回一个List结构的选择器,所以你也可以对其再次调用选择方法:
>>> links = response.xpath('//a[contains(@href, "image")]')>>> links.extract()[u'<a href="image1.html">Name: My image 1 <br><img src="image1_thumb.jpg"></a>', u'<a href="image2.html">Name: My image 2 <br><img src="image2_thumb.jpg"></a>', u'<a href="image3.html">Name: My image 3 <br><img src="image3_thumb.jpg"></a>', u'<a href="image4.html">Name: My image 4 <br><img src="image4_thumb.jpg"></a>', u'<a href="image5.html">Name: My image 5 <br><img src="image5_thumb.jpg"></a>']>>> for index, link in enumerate(links):... args = (index, link.xpath('@href').extract(), link.xpath('img/@src').extract())... print 'Link number %d points to url %s and image %s' % argsLink number 0 points to url [u'image1.html'] and image [u'image1_thumb.jpg']Link number 1 points to url [u'image2.html'] and image [u'image2_thumb.jpg']Link number 2 points to url [u'image3.html'] and image [u'image3_thumb.jpg']Link number 3 points to url [u'image4.html'] and image [u'image4_thumb.jpg']Link number 4 points to url [u'image5.html'] and image [u'image5_thumb.jpg']
- Scrapy学习二:基本概念进阶(未完成)
- 【Scrapy】Scrapy学习(二)——基本概念
- JavaScript 学习(二):语法(未完成)
- Scrapy学习笔记(二)
- (未完成)学习方法(二)
- 学习MQ(二)基本概念
- 机器学习基本概念(二)
- python 爬虫学习二(Scrapy讲解)
- Scrapy爬虫笔记-未完成
- VC学习(未完成)
- Ajax进阶学习(二)
- Scrapy的Ip代理的配置(未完成)
- D-Bus学习(二):基本概念
- MongoDB学习(二):数据类型和基本概念
- D-Bus学习(二):基本概念
- MongoDB学习(二):数据类型和基本概念
- MongoDB学习(二):数据类型和基本概念
- MongoDB学习(二):数据类型和基本概念
- 浅谈GIT
- python.装饰器
- 项目使用3D检查UI布局渲染
- Git使用简介
- 20多个可以提高你安卓开发技能的开源app
- Scrapy学习二:基本概念进阶(未完成)
- Linux(deepin)在终端配置使用git
- Android——常用设计模式
- linux(5)
- c51上跑smallrtos 之ds1302 存取日期
- 程序员需要关注的十个大数据技术
- JS数组中的常用方法
- 百练2981: 大整数加法
- leejianjun的博客 微信Access_token