一、XPath
(1)使用路径表达式:
表达式 | 内容 |
---|
nodename | 选取此节点的所有子节点 |
/ | 从根节点选取 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑他们的位置 |
. | 选取当前节点 |
… | 选取当前节点的父节点 |
@ | 选取属性 |
[@attrib] | 选取具有给定属性的所有元素 |
[@attrib=‘value] | 选取给定属性具有给定值的所有元素 |
[tag] | 选取所有具有指定元素的直接子节点 |
[tag=‘text] | 选取所有具有指定元素并且文本内容是text节点 |
(2)选取未知节点:(使用通配符)
匹配符 | 内容 |
---|
* | 匹配任何元素节点 |
@* | 匹配任何属性节点 |
node() | 匹配任何类型的节点 |
(3)xpath基本语法:
1.路径查询
- // 查找子孙节点,不考虑层级关系
- / 直接查找子节点
2.谓词查询
- //div[@id]
- //div[@id=‘head’]
3.属性查询
4.模糊查询
- //div[contains(@id,‘he’)]
- //div[starts-with(@id,‘he’)]
5.内容查询
6.逻辑查询
- //div[@id=‘head’ and @class=‘s_down’]
- //title | //price
二、jsonpath
链接: 详细jsonpath用法
三、BeautifulSoup
(1)bs4的一些函数
1.find(返回一个对象)
soup.find('a') 返回的是第一个符合条件的数据
soup.find('a',title='a1') 根据title的值来找到对应的标签对象
soup.find('a',class_='a2') 根据class的值来找到对应的标签对象 注意class需要在添加下划线
2.find_all (放回一个列表)
soup.find_all('a') 返回一个列表 并且返回了所有的a标签
soup.find_all(['a','span']) 如果想要多个标签的数据 那么需要在find_all的参数中添加的是列表的数据
soup.find_all('li',limit=2) limit限制选取的数据
3.select (根据选择器得到节点对象) 【推荐】
soup.select('a') 放回一个列表,多个数据
soup.select('.a1') 可以通过.代表class -->类选择器
soup.select('#l1') 可以通过#代表id
soup.select('li[id]') 查找有id的li标签 -->属性选择器
soup.select('li[id='l20']') 查找id等于l2的li标签
soup.select('div li') 找到div下面的li 后代选择器 -->层级选择器
soup.select('div > ul > li') 某标签的第一级子标签 子代选择器 -->层级选择器
soup.select('li,a') 找到a标签和li标签的所有的对象
(2)节点信息
1.获取节点内容:适用于标签中嵌套标签的结构
obj.string
obj.get_text() ---常用
2.节点属性
tag.name 获取标签名
tag.attrs将属性值作为一个字典返回
3.获取节点属性内容
obj.attrs.get('title') ---常用
obj.get('title')
obj['title']
四、案例
(1)获取百度网站的‘百度一下’四个字
import urllib.request
from lxml import etree
url = 'https://www.baidu.com/'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.0.7062 SLBChan/105'
}
request = urllib.request.Request(url=url,headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
html_str = etree.HTML(content)
result = html_str.xpath("//input[@id='su']/@value")
print(result)
(2)bs4爬取星巴克菜单数据
import urllib.request
from bs4 import BeautifulSoup
import os
url = 'https://www.starbucks.com.cn/menu/'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.0.7062 SLBChan/105'
}
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
soup = BeautifulSoup(content, 'lxml')
obj_name = soup.select('strong')
name_list = []
for i in range(0, len(obj_name)):
name_list.append(obj_name[i].get_text())
img_list = []
obj_img = soup.select("ul li a div[class='preview circle']")
for i in range(0, len(obj_img)):
img_list.append('https://www.starbucks.com.cn' + obj_img[i].attrs.get('style').split('"')[1])
if not os.path.exists('xbk_menu'):
os.mkdir('xbk_menu')
for i in range(len(img_list)):
link = img_list[i]
fn = name_list[i].replace('/', ',')
urllib.request.urlretrieve(link, 'xbk_menu/' + fn + '.jpg')