Xpath与bs4解析器基础(有案例代码)
1,xpath解析器概念
首先,我们来讲解一下xpath语法及相关知识。
XPath 使用路径表达式来选取HTML/ XML 文档中的节点或节点集。节点是通过沿着路径 (path) 或者步 (steps) 来选取的。
在这里我们需要下载一下lxml
- 第一个方法是打开cmd,输入pip install lxml
- 第二个则是在文件–设置–python解释器–在搜索到这个包然后下载
表达式 | 描述 |
---|---|
nodename | 选取此节点的所有子节点 |
/ | 从根节点选取(取子节点) |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置(去子孙节点) |
. | 选取当前节点 |
… | 选取当前节点的父节点 |
@ | 选取属性 |
为了方便理解,我们可以作出如下案例解释
例如,我们要在一个全国范围内查找张三
首先我们可以在全国范围内查找张三的学校(文昌中学)
首先我们可以 // 文昌中学,然后我们可以通过./来查找张三所在的班级三年二班,最后通过一个/来查找张三
//文昌中学
./三年二班/张三
同时,我们此时还知道张三的父亲是一个区长。这个时候我们就可以使用@来选取属性。
张三[@“区长”]快速查找到张三的一些相关信息。
1)etree用法
这里我们要了解一下etree的主要函数:
- etree.HTML():解析字符串格式的HTML文档对象,将字符串参数变为Element对象,以便使用xpath()等方法;
- etree.tostring():将Element对象转换成字符串;
- etree.fromstring():将字符串转换成Element对象。
案例:
例如我们随机去抓取一个标题,房价
代码如下:
# 爬虫 -- 长沙二手房
import requests
from lxml import etree
class Changshai_house(object):
def __init__(self):
self.url = "https://cs.anjuke.com/sale/?pi=360-cpc-cs-ty1&kwid=7162913759&utm_term=%E9%95%BF%E6%B2%99%E4%BA%8C%E6%89%8B%E6%88%BF%E5%87%BA%E5%94%AE%E4%BF%A1%E6%81%AF"
self.headers = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.57"
}
def get_data_index(self):
resp = requests.get(url=self.url, headers=self.headers)
if resp.status_code == 200:
return resp.text
else:
return None
def parse_data_index(self, respoonse):
html = etree.HTML(respoonse)
#解析页面
dict_data = html.xpath("//div[@class='property']")
for data in dict_data:
item = data.xpath("./a/div[@class='property-content']/div/div/h3/text()")[0]
money = data.xpath("./a/div[2]/div[2]/p[@class='property-price-total']/span/text()")[0]
print(area)
#self.save_data(item)
def save_data(self, response):
with open("房价信息.text", "a", encoding="utf-8") as f:
f.write(response + '\n')
def run(self):
resp = self.get_data_index()
self.parse_data_index(resp)
if __name__ == '__main__':
spider = Changshai_house()
spider.run()
结果如下:
2,bs4解析器概念
首先,我们还是按照上面的方法下载bs4解析器
首先我们来看看bs4解析器的一些方法
print(soup.title)
# <ittle>The Dormouse's story</title>
#打印标头名字
print(soup.title.name)
# u'title'
#打印内容
print(soup.title.string)
# u'The Dormouse's story'
#打印p标签
print(soup.p)
# <p class="title"><b>The Dormouse's story</b></p>
#打印claa属性
print(soup.p['class'])
# u'title'
print(soup.a)
# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
#这是常用方法之一,查找到id属性为link3
print(soup.find(id="link3"))
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
print(soup.find_all('a'))
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
注意
在我们python中有一个class关键字,代表类,而html标签里面也有一个class,这时如果我们要查找class属性时,应该在class后面加一个下划线_
当然,我们也可以用css选择器来搜索,但是因为不常用,所以在这里就不介绍了,如有需要可以联系作者哟~
案列,例如我们去爬取美女图片,嘿嘿嘿,咳咳,当然是正经图片
在这里我们需要调用一下这个包
from bs4 import BeautifulSoup
其余部分和上述一样,但是在解析这一块,我们需要作出更改
def parse_image_girl(self, response):
soup = BeautifulSoup(response, "lxml")
image_data = soup.find_all("img", alt="美女")
for data in image_data:
href = data.get("src")
self.save_image_girl(href)
在这里我们还需要注意,图片一般是以二进制字节码文件保存哦,所以我们的写入方式应该是"wb",而且获取的字符串后面应该加入一个.content
成果图如下:
3,最后在这里我们来说一下两者的优劣吧!
解析器 | 使用方法 | 优势 | 劣势 |
---|---|---|---|
Python标准库 | BeautifulSoup(markup, "html.parser") | Python的内置标准库执行速度适中文档容错能力强 | Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差 |
lxml HTML 解析器 | BeautifulSoup(markup, "lxml") | 速度快文档容错能力强 | 需要安装C语言库 |
建议大家可以先从简单点的入手,如爬取一些的logo呀之类的。
不足之处,欢迎大家进行指正!!!!