xpath解析
在XML文档中查找信息的语言,同样适用于HTML文档的检索
xpath工具
Chrom插件 Xpath Helper
打开 ctrl + shift + x
Firefox插件 Xpath checker
选取节点
- 路径表达式
表达式 | 描述 |
---|---|
nodename | 选取此节点的所有子节点。 |
/ | 从根节点选取。 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
. | 选取当前节点。 |
.. | 选取当前节点的父节点。 |
@ | 选取属性。 |
- | 多路径匹配(或)
xpath表达式1 | xpath表达式2
路径表达式 | 结果 |
---|---|
bookstore | 选取 bookstore 元素的所有子节点。 |
/bookstore | 选取根元素 bookstore。 |
注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径! | |
bookstore/book | 选取属于 bookstore 的子元素的所有 book 元素。 |
//book | 选取所有 book 子元素,而不管它们在文档中的位置。 |
bookstore//book | 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。 |
//@lang | 选取名为 lang 的所有属性。 |
- 函数
- contains() 匹配一个属性值中 包含某些字符串的节点
//title[contains(@lang, ‘e’)] 获取节点对象 - text() 获取文本
//title[contains(@lang, ‘e’)]/text() 获取的是节点内容
- contains() 匹配一个属性值中 包含某些字符串的节点
使用
- 导模块
from lxml import etree - 创建解析对象
parseHtml = etree.HTML(html) - 调用xpath
rList = parseHtml.xpath(‘xpath表达式’)调用xpath,返回的一定为列表
xpath解析例子
from lxml import etree
html = '''
<div class="wrapper">
<i class="iconfont icon-back" id="back"></i>
<a href="/" id="channel">新浪社会</a>
<ul id="nav">
<li><a href="http://domestic.firefox.sina.com/" title="国内">国内</a></li>
<li><a href="http://world.firefox.sina.com/" title="国际">国际</a></li>
<li><a href="http://mil.firefox.sina.com/" title="军事">军事</a></li>
<li><a href="http://photo.firefox.sina.com/" title="图片">图片</a></li>
<li><a href="http://society.firefox.sina.com/" title="社会">社会</a></li>
<li><a href="http://ent.firefox.sina.com/" title="娱乐">娱乐</a></li>
<li><a href="http://tech.firefox.sina.com/" title="科技">科技</a></li>
<li><a href="http://sports.firefox.sina.com/" title="体育">体育</a></li>
<li><a href="http://finance.firefox.sina.com/" title="财经">财经</a></li>
<li><a href="http://auto.firefox.sina.com/" title="汽车">汽车</a></li>
</ul>
<i class="iconfont icon-liebiao" id="menu"></i>
</div>
'''
# 创建解析对象
paresHtml = etree.HTML(html)
# 调用xpath返回结果
def xp(x):
rList = paresHtml.xpath(x)
print(rList)
xp('//ul//a/text()')
#Out:['国内', '国际', '军事', '图片', '社会', '娱乐', '科技', '体育', '财经', '汽车']
xp('//ul/li/a/@href')
#Out:['http://domestic.firefox.sina.com/', 'http://world.firefox.sina.com/', 'http://mil.firefox.sina.com/', 'http://photo.firefox.sina.com/', 'http://society.firefox.sina.com/', 'http://ent.firefox.sina.com/', 'http://tech.firefox.sina.com/', 'http://sports.firefox.sina.com/', 'http://finance.firefox.sina.com/', 'http://auto.firefox.sina.com/']
爬虫案例
抓取目标图片
思路
模特链接列表 = parseHtml.xpath('..') for 模特链接 in 模特链接列表: 图片链接列表 = 对模特发请求后xpath for 图片链接 in = 图片链接列表: html = 对图片连接发请求 with open(filename, 'wb') as f: f.write(html)
步骤
1.获取主页URL,寻找URl规律
http://www.tmt001.com/
2.xpath
List : //div[@class=’result_models’]/ul/li/div[@class=’model_data’]/a/@href
name : //div[@class=’result_models’]/ul/li/div[@class=’model_data’]/a/text()
jpgList ://dd/img/@src
jpgname : name+01
爬虫代码
from lxml import etree
import requests
import time
class TotSpider(object):
def __init__(self):
self.baseurl = 'http://www.tmt001.com/'
self.headers = {'User-Agent':''}
def getPage(self, url, xp=None):
res = requests.get(url=url, headers=self.headers)
if xp == None:
return res.content
res.encoding = 'utf-8'
html = res.text
return self.parsePage(html, xp)
def parsePage(self, html, xp):
paresHtml = etree.HTML(html)
rList = paresHtml.xpath(xp)
return rList
def writeJpg(self, html, filename):
with open(filename, 'wb') as f:
f.write(html)
def workOn(self):
menu = '''
\033[32m********************
--- 1.爬取 ---
--- 2.退出 ---
********************
请选择(1/2):\033[0m
'''
cmd = input(menu)
if cmd.strip() == '1':
n = input('请输入页数>>>')
if n.strip().isdigit():
n = int(n)
for page in range(1, n+1):
url =self.baseurl + '?c=article&a=search&xb=2&page=' + str(page)
xp_a = "//div[@class='result_models']/ul/li/div[@class='model_data']/a/@href"
xp_name = "//div[@class='result_models']/ul/li/div[@class='model_data']/a/text()"
rList_a = self.getPage(url, xp_a)
# print(rList_a)
rList_name = self.getPage(url, xp_name)
for rt_a, filename in zip(rList_a, rList_name):
url = self.baseurl + rt_a
xp = '//dd/img/@src'
rList_jpg = self.getPage(url, xp)
for name, rt_j in enumerate(rList_jpg):
url = self.baseurl + rt_j
html = self.getPage(url)
file_name = 'tot/' + filename + str(name) + '.jpg'
self.writeJpg(html, file_name)
time.sleep(0.2)
else:
print('over')
if __name__ == '__main__':
spider = TotSpider()
spider.workOn()
博主个人能力有限,错误在所难免.
如发现错误请不要吝啬,发邮件给博主更正内容,在此提前鸣谢.
Email: JentChang@163.com (来信请注明文章标题,如果附带链接就更方便了)
你也可以在下方的留言板留下你宝贵的意见.