python爬虫爬虫python

爬虫技术详解(一)- XPath

2018-02-23  本文已影响85人  geekpy

XPath简介


以下摘自维基百科

XPath (XML Path Language) is a query language for selecting nodes from an XML document. In addition, XPath may be used to compute values (e.g., strings, numbers, or Boolean values) from the content of an XML document. XPath was defined by the World Wide Web Consortium (W3C).

简单来说就是用于XML/HTML文档的查询语言。我们在爬虫中程序中使用XPath主要用于定位HTML文档中的节点。比如获取HTML文档中通过href属性标识的URL地址。更详细的介绍请参考XPath简介

XPath使用场景


在爬虫技术领域里为什么需要XPath呢?这是因为我们通过爬虫去网上爬取的很多都是html文档(比如爬知乎,爬微博),而我们通常需要对html数据进行解析,获取对我们有用的数据,然后再将这些处理后的数据存储起来。而解析HTML就需要用到XPath。(另外也可以通过css query来定位节点,但是一般其背后也是利用了XPath技术,而且XPath更加灵活和通用)

基本概念解释


在理解XPath之前我们首先要了解一些基本的概念:

<?xml version="1.0" encoding="ISO-8859-1"?>

<!--this is a xml demo-->
<bookstore>

<book>
  <title lang="en">Harry Potter</title>
  <author>J K. Rowling</author> 
  <year>2005</year>
  <price>29.99</price>
</book>
<book>
  <title lang="en">Black Swan</title>
  <author>Nassim Nicholas Taleb</author> 
  <year>2010</year>
  <price>12.23</price>
</book>

</bookstore>

节点(Node)

XML节点一共有七种,如下:

<table xmlns="http://www.w3.org/TR/html4/">
   <tr>
   <td>Apples</td>
   <td>Bananas</td>
   </tr>
</table>
<!--this is a xml demo-->

节点之间的关系

节点之间的关系主要有以下几种:

了解节点关系,主要用于后边路径表达式的轴,详见路径表达式小节。

XPath的路径表示


在进一步了解XPath的相关概念之前,我们最好可以通过实际的演练来看下XPath到底是什么。所以首先我们来配置一下测试的环境。

环境准备

安装scrapy。scrapy是一个爬虫框架,我们将通过scrapy提供的shell功能来对XPath做实验。

pip install -u scrapy

注意:在Mac环境下需要创建一个虚拟环境,否则无法安装成功

> scrapy shell 'http://www.163.com'
2018-02-22 21:39:05 [scrapy.utils.log] INFO: Scrapy 1.5.0 started (bot: ifanrcrawler)
2018-02-22 21:39:05 [scrapy.utils.log] INFO: Versions: lxml 4.1.1.0, libxml2 2.9.7, cssselect 1.0.3, parsel 1.4.0, w3lib 1.19.0, Twisted 17.9.0, Python 2.7.13 (default, May  7 2017, 10:23:30) - [GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.41)], pyOpenSSL 17.5.0 (OpenSSL 1.1.0g  2 Nov 2017), cryptography 2.1.4, Platform Darwin-17.4.0-x86_64-i386-64bit
2018-02-22 21:39:05 [scrapy.crawler] INFO: Overridden settings: {'NEWSPIDER_MODULE': 'ifanrcrawler.spiders', 'ROBOTSTXT_OBEY': True, 'DUPEFILTER_CLASS': 'scrapy.dupefilters.BaseDupeFilter', 'SPIDER_MODULES': ['ifanrcrawler.spiders'], 'BOT_NAME': 'ifanrcrawler', 'LOGSTATS_INTERVAL': 0, 'COOKIES_ENABLED': False}
2018-02-22 21:39:05 [scrapy.middleware] INFO: Enabled extensions:
['scrapy.extensions.memusage.MemoryUsage',
 'scrapy.extensions.telnet.TelnetConsole',
 'scrapy.extensions.corestats.CoreStats']
2018-02-22 21:39:05 [scrapy.middleware] INFO: Enabled downloader middlewares:
['scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware',
 'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',
 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',
 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',
 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',
 'scrapy.downloadermiddlewares.retry.RetryMiddleware',
 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',
 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',
 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',
 'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware',
 'scrapy.downloadermiddlewares.stats.DownloaderStats']
2018-02-22 21:39:05 [scrapy.middleware] INFO: Enabled spider middlewares:
['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',
 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',
 'scrapy.spidermiddlewares.referer.RefererMiddleware',
 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',
 'scrapy.spidermiddlewares.depth.DepthMiddleware']
2018-02-22 21:39:05 [scrapy.middleware] INFO: Enabled item pipelines:
[]
2018-02-22 21:39:05 [scrapy.extensions.telnet] DEBUG: Telnet console listening on 127.0.0.1:6023
2018-02-22 21:39:05 [scrapy.core.engine] INFO: Spider opened
2018-02-22 21:39:05 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://www.163.com/robots.txt> (referer: None)
2018-02-22 21:39:05 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://www.163.com> (referer: None)
[s] Available Scrapy objects:
[s]   scrapy     scrapy module (contains scrapy.Request, scrapy.Selector, etc)
[s]   crawler    <scrapy.crawler.Crawler object at 0x10f5269d0>
[s]   item       {}
[s]   request    <GET http://www.163.com>
[s]   response   <200 http://www.163.com>
[s]   settings   <scrapy.settings.Settings object at 0x10f526a50>
[s]   spider     <DefaultSpider 'default' at 0x10f9a6f90>
[s] Useful shortcuts:
[s]   fetch(url[, redirect=True]) Fetch URL and update local objects (by default, redirects are followed)
[s]   fetch(req)                  Fetch a scrapy.Request and update local objects
[s]   shelp()           Shell help (print this help)
[s]   view(response)    View response in a browser
>>> 
>>> title = response.xpath('//title').extract_first()
>>> title
u'<title>\u7f51\u6613</title>'
>>> title = response.xpath('//title/text()').extract_first()
>>> title
u'\u7f51\u6613'
>>> print title
网易

路径表达式

XPath通过路径表达式来定位节点。

语法
XPath运算符

可用的运算符如下:

运算符 描述 实例 返回值
| 计算两个节点集 //book | //cd 返回所有拥有 book 和 cd 元素的节点集
+ 加法 6 + 4 10
- 减法 6 - 4 2
* 乘法 6 * 4 24
div 除法 8 div 4 2
= 等于 price=9.80 如果 price 是 9.80,则返回 true。如果 price 是 9.90,则返回 false。
!= 不等于 price!=9.80 如果 price 是 9.90,则返回 true。如果 price 是 9.80,则返回 false。
< 小于 price<9.80 如果 price 是 9.00,则返回 true。如果 price 是 9.90,则返回 false。
<= 小于或等于 price<=9.80 如果 price 是 9.00,则返回 true。如果 price 是 9.90,则返回 false。
> 大于 price>9.80 如果 price 是 9.90,则返回 true。如果 price 是 9.80,则返回 false。
>= 大于或等于 price>=9.80 如果 price 是 9.90,则返回 true。如果 price 是 9.70,则返回 false。
or price=9.80 or price=9.70 如果 price 是 9.80,则返回 true。如果 price 是 9.50,则返回 false。
and price>9.00 and price<9.90 如果 price 是 9.80,则返回 true。如果 price 是 8.50,则返回 false。
mod 计算除法的余数 5 mod 2 1

通过运算符我们可以选取符合特定条件的节点。

Reference

上一篇下一篇

猜你喜欢

热点阅读