python爬虫系列(七):XPath的使用

(一)简介与安装

之前我们了解了bs4 处理HTML文档,今天来看看另一种方式,就是lxml,也就是XPath类库。我们可以先将HTML文件转换为XML文档,然后用Xpath查找自己想要的内容的所在节点就可以了。那么XML被设计为传输和存储数据,焦点是数据的内容,而页面HTML则是显示数据以及更好的显示数据。
安装很简答,用我们的老朋友pip 进行安装即可。pip install lxml,而不是XPath呢!

(二)什么是XPath和开发工具

·xpath (XML Path Language) 是一门在XML文档中查找信息的语言,可用来在XML文档中对元素和属性进行遍历。
·XPath开发工具
1.开源的XPath表达式编辑工具:XMLQuire(xml文件可用)
2.Chrome插件Xpath helper
3.Firefox插件 Xpath checker
4.博主常用的就是浏览器自带的验证xpath匹配的工具,方法很简单。在网页界面按F12进入开发者工具界面,然后按快捷键Ctrl+F
即可编写自己的xpath语句,显示框后面显示出匹配出的个数。

(三): 如何使用xpath呢

1)选取节点

xpath 使用路径表达式来选取xml文档中的节点或者节点集。


表达式            描述
nodename     选取此节点的所有子节点。
/            从根节点选取。
//           从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
.            选取当前节点。
..           选取当前节点的父节点。
@            选取属性。

2)谓语

我们也可以用谓语来查找某个特定的节点或者包含某个指定的值的节点,被潜在方括号里面。我们使用下面的这段HTML节点进行演示。如何使用谓语。



<bookstore>

<book>
  <title>Harry Pottertitle>
  <author>J K. Rowlingauthor>
  <year>2005year>
  <price>29.99price>
book>
bookstore>

下面就是带有谓语的一些路径表达式,以及表达式的结果:

路径表达式                           结果
/bookstore/book[1]                  选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/book[last()]             选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1]           选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()<3]       选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
//title[@lang]                      选取所有拥有名为 lang 的属性的 title 元素。
//title[@lang=’eng’]                选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。
/bookstore/book[price>35.00]         选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。
/bookstore/book[price>35.00]/title    选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00

3)选取未知元素

我们可以使用xpath的通配符可用来选取未知的xml元素


通配符                    描述
*                       匹配任何元素节点。
@*                      匹配任何属性节点。
node()                  匹配任何类型的节点。
/bookestore/*           选取bookestore元素的所有子元素
//*                     选取文档中的所有的元素
//title[@*]             选取所有带有属性的title元素

基本上爬虫匹配中用到的也就这么多了,下面进行代码演示就和容易get到这个必备的爬虫装备了。

(四)代码演示

话不多说上代码:可以先试试跑出来的什么东西,相信你会喜欢的

from urllib import request
from lxml import etree
import random
#为了防止百度的反爬虫技术,我选择了随机的选择代理浏览器的方法
user_agent_list = [
     'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
     'Chrome/45.0.2454.85 Safari/537.36 115Browser/6.0.3',
     'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
     'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
     'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)',
     'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)',
     'Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1',
     'Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11',
     'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',
     'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SE 2.X MetaSr 1.0; SE 2.X MetaSr 1.0; .NET CLR 2.0.50727; SE 2.X MetaSr 1.0)',
     'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0',
     'Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1',
]
#获得链接的函数
def get_link(url):
    userAgent = random.choice(user_agent_list)
    headers = {'User-Agent':userAgent}
    proxy = request.ProxyHandler({"http":"61.160.208.222:8080"})
    opener = request.build_opener(proxy)
    #将带有代理的请求设置成全局的请求类
    request.install_opener(opener)
    req = request.Request(url,headers=headers)
    response = request.urlopen(req)
    #注意python2 和 Python3 的编码问题
    html = response.read().decode('utf-8')
    print(html)
    #将HTML解析下
    content = etree.HTML(html)
    #用xpath解析出页面中的链接,匹配出的类型是列表格式。
    link_list = content.xpath('//div[@class="t_con cleafix"]/div/div/div/a/@href')
    for link in link_list:
        fulllink = "http://tieba.baidu.com" + link
        loadImage(fulllink)
#下载图片的函数
def loadImage(url):
    userAgent = random.choice(user_agent_list)
    headers = {"User-Agent":userAgent}
    req = request.Request(url,headers=headers)
    response = request.urlopen(req)
    html = response.read()
    content = etree.HTML(html)
    linklist = content.xpath('//img[@class="BDE_Image"]/@src')
    for link in linklist:
        saveImage(link)
#保存到本地
def saveImage(link):
    filename = "teibabeauty/"+link[-10:]
    try:
        request.urlretrieve(link,filename=filename)
        print(link)
    except Exception as e:
        print(e)
if __name__=="__main__":
    url = r"https://tieba.baidu.com/f?kw=%E7%BE%8E%E5%A5%B3&ie=utf-8&tab=good&cid=&pn=400"
    get_link(url)

你可能感兴趣的:(爬虫)