python爬虫-bs4模块和xpath模块
bs4模块
安装
pip install bs4
使用
# 导入
from bs4 import BeautifulSoup
# 实例化对象(指定需要解析的文件或者页面源码)
fp = open('a.html', 'r', encoding='utf-8')
page_text = requests.get(url, headers=headers)
soup = BeautifulSoup(fp/page_text, 'lxml')
# 定位
## 标签定位
soup.p # soup.tagName 只可以返回符合条件的第一个标签
## 属性定位
soup.find('div', id='haha') # soup.find('tagName', attrName='value') 找到div中id为haha的一段,返回是单数
## 注意: class属性应写成class_
soup.find_all('div', class_='haha') # 返回是所有符合的数据,返回是列表
## select选择器(大于号表示一个层级,空格表示多个层级)
soup.select('.haha > ul > li') # 找到class=haha下面一层的ul下面一层的li数据,返回是列表
soup.select('.haha ul') # 找到class=haha下面的所有ul数据,返回是列表
# 数据提取
a_tag = soup.select('.a')[0] # 定位到class=a的第一条标签数据
a_tag.string # 获取标签中直系的文本内容
a_tag.text # 获取标签中所有的文本信息
a['href'] # 获取标签中的属性数据
xpath模块
安装
pip install lxml
使用
# 导入
from lxml import etree
# 实例化一个etree对象
tree = etree.HTML(page_text) # HTML --> 网页源码
tree = etree.parse(filePath) # parse --> 文件路径
# 注意: xpath返回的都是列表
# 标签定位
tree.xpath('/html') # 最左侧的/,必须从根节点开始(/html)
tree.xpath('//title') # 最左侧的//,从任意位置开始定位
tree.xpath('//title/div/a') # 非左侧的/,表示一个层级,title下面的div下面的a标签
tree.xpath('//title//a') # 非左侧的//,表示多个层级,title下面的所有的a标签
tree.xpath('//title[@name="aaa"]') # 通过指定属性定位,找到有name="aaa"属性的title
tree.xpath('//title/div[1]') # 通过指定索引定位,找到title下面的第一个div标签,索引从1开始
# 数据提取
tree.xpath('//title/text()') # /text() 提取title标签直系的文本信息
tree.xpath('//title//text()') # //text() 提取title标签中所有的文本信息
tree.xpath('//title/@src') # 提取title标签中的src属性值
补充
浏览器中支持直接复制xpath路径
在提取到的标签数据上再提取数据
from lxml import etree
...
tree = etree.HTML(page_text)
li_list = tree.xpath('//div[@class="menu"]/ul/li') # 返回的是一个li列表
for li in li_list:
li.xpath("./p//text()")[0] # 局部解析,必须加上./
...
xpath管道符的使用
# 可以同时提取出class=menu和class=content的标签数据列表,是xpath表达式有更强的通用性
tree.xpath('//div[@class="menu"]/ul/li | //div[@class="content"]/ul/li')
当class属性中有多个值时
# class="a b"
tree.xpath('//div[@class="a"]') # 这个是提取不出来的
# 解决
tree.xpath('//div[contains(@class, "a")]')