小爬虫学习——网页解析工具(bs4xpath)
Posted 别呀
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小爬虫学习——网页解析工具(bs4xpath)相关的知识,希望对你有一定的参考价值。
一、BS4
1.1、前沿
BeautifulSoup 是一个可以从html或XML文件中提取数据的Python库,它的使用方式相对于正则来说更加的简单方便,常常能够节省我们大量的时间。(我这里只是简单介绍bs4使用,想了解更多的小伙伴可以参考:官方中文文档)
安装
pip install beautifulsoup4
解析器
解析器 | 使用方法 | 优势 | 劣势 |
---|---|---|---|
Python标准库 | BeautifulSoup(markup, “html.parser”) | Python的内置标准库执行速度适中文档容错能力强 | Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差 |
lxml HTML 解析器 | BeautifulSoup(markup, “lxml”) | 速度快文档容错能力强 | 需要安装C语言库 |
lxml XML 解析器 | BeautifulSoup(markup, [“lxml”, “xml”]),BeautifulSoup(markup, “xml”) | 速度快唯一支持XML的解析器 | 需要安装C语言库 |
html5lib | BeautifulSoup(markup, “html5lib”) | 最好的容错性以浏览器的方式解析文档生成HTML5格式的文档 | 速度慢不依赖外部扩展 |
由于这个解析的过程在大规模的爬取中是会影响到整个爬虫系统的速度的,所以推荐使用的是lxml,速度会快很多,而lxml需要单独安装:pip install lxml
提示:如果一段HTML或XML文档格式不正确的话,那么在不同的解析器中返回的结果可能是不一样的,所以要指定某一个解析器。
基本语法
(往下的示例均以下面的这个HTML代码作为案例)
html_str="""<!DOCTYPE html>
<html>
<head>
<title>爬虫</title>
<meta charset="utf-8">
<link rel="stylesheet" href="http://www.taobao.com">
<link rel="stylesheet" href="https://www.baidu.com">
<link rel="stylesheet" href="http://at.alicdn.com/t/font_684044_un7umbuwwfp.css">
</head>
<body>
<!-- footer start -->
<footer id="footer">
<div class="footer-box">
<div class="footer-content" >
<p class="top-content" id="111">
<a href="http://www.taobao.com">淘宝</a>
<span class="link">
<a class="product" href="https://www.baidu.com">关于Python</a>
<a href="http://www.taobao.com">好好学习</a>
<a href="javascript:void(0)">人生苦短</a>
<a href="javascript:void(0)">我用Python</a>
</span>
<span class="about-me">关于我: <i class="PyWhich py-wechat"></i> 忽略</span>
</p>
<p class="bottom-content">
<span>地址: xxxx</span>
<span>联系方式: <a href="tel:400-1567-315">400-1567-315</a> (24小时在线)</span>
</p>
</div>
<p class="copyright-desc">
Copyright © 爬虫有限公司. All Rights Reserved
</p>
</div>
</footer>
</body>
</html>
"""
from bs4 import BeautifulSoup#导包
soup=BeautifulSoup(html_str,'lxml') #html_str:HTML代码
type(soup) #结果:bs4.BeautifulSoup
1.2、获取标签
格式:soup.标签
(注意这里的soup是上面初始化的)
示例:
soup.a #获取第一个符合条件的标签
#结果: <a href="http://www.taobao.com">淘宝</a>
1.3、获取标属性
格式:soup.标签['属性名']
示例:
soup.a['href']
#结果:'http://www.taobao.com'
1.4、获取内容
格式:soup.标签.text
示例:
soup.a.text
#结果:'淘宝'
1.5、亲戚标签的选择
(有兴趣的自己去运行下,我这里就不运行了)
示例:
body=soup.body
list(body.children)#获取 儿子标签 仅仅是儿子 body.children迭代器
body.contents#获取 儿子元素 到列表中
body.descendants #获取所有的后代元素标签 生成器(转成list可以打印结果)
p=body.p #获取第一个符合条件的p标签
p.next_sibling.next_sibling#获取下一个兄弟元素
body.previous_sibling.previous_sibling#获取上一个兄弟元素
p_parents=p.parents #获取所有的父辈元素 生成器
1.6、find_all
def find_all(name=None, attrs={}, recursive=True, text=None):
#作用:查找元素 返回值是存储在列表中
#name 标签名字
#attrs 属性
#recursive 递归 只能获取到 子元素
#text 标签内容
pass
示例:
a=soup.find_all("a",text="淘宝")#根据标签名查找所有元素 标签内容 筛选定位元素
print(a) #结果: [<a href="http://www.taobao.com">淘宝</a>]
p=soup.find_all("p",attrs={"class":"top-content"})#名字 属性定位 元素
html=soup.find_all("html",recursive=False)#只获取子元素
1.7、CSS选择器
示例:
soup.select("p") #根据名字获取所有元素
soup.select("p > span") #获取所有p标签下 所有的子代span元素
soup.select("p span") #获取所有p标签下 所有的span元素
soup.select('.top-content') #获取class为top-content的元素
soup.select('#111') #获取id为111 的元素
二、Xpath
基本语法
from lxml import etree #导包
page=etree.HTML(html_str) #结果:<Element html at 0x27ed6712cc8>
2.1、标签选择与属性值的选择
示例:
page.xpath('/html/body') #从根路径开始,层层筛选 /:表示下一级的元素
#结果:[<Element body at 0x163035a6b80>]
p=page.xpath("//p") #获取所有p标签元素 存在列表中
p[0].xpath('./a') # . : 表示当前元素标签
#结果:[<Element a at 0x1630358ff00>]
a=page.xpath("//a")[0]
a.xpath('..') #.. :当前节点的父节点
page.xpath("body")#根据标签名字 获取元素 只能拿到子标签
#[<Element body at 0x163035a6b80>]
p=page.xpath('//p[@class="top-content"]')#根据属性获取标签
#[<Element p at 0x27ed684a948>]
attr_value=page.xpath('//p[@class="bottom-content"]/span') #获取标签属性值
# [<Element span at 0x16303589dc0>, <Element span at 0x16303596640>]
page.xpath("//*") #获取所有标签元素
tags=page.xpath('//p[@class="top-content"]/a[1]') #xpath 规则 从1开始
#[<Element a at 0x27ed6712f08>]
2.2、获取文本
示例:
contents=page.xpath("//p/a/text()") #获取标签内容 在列表中
# ['淘宝', '关于Python', '好好学习', '人生苦短', '我用Python', '优秀']
con_all=page.xpath("string(//html)")#获取标签下所有内容
2.3、语法总结
- 常用
XPath 使用路径表达式在 XML/HTML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。
下面列出了最有用的路径表达式:
表达式 | 描述 |
---|---|
nodename | 选取当前节点的所有nodename子节点 |
/ | 从根节点选取 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
. | 选取当前节点 |
.. | 选取当前节点的父节点 |
@ | 选取属性 |
- 谓语
谓语用来查找某个或某些特定的节点或者包含某个指定值的节点谓语被嵌在方括号中。
实例:
在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果。
路径表达式 | 结果 |
---|---|
//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。 |
- Xpath通配符,选取未知节点
通配符 | 描述 | 路径表达式 | 结果 |
---|---|---|---|
* | 匹配任何元素节点 | //bookstore/* | 选取bookstore元素的所有子元素。 |
@* | 匹配任何属性节点 | //* | 选取文档中国的所有元素 |
node() | 匹配任何类型的节点 | //title[@*] | 选取所有带有属性的title元素 |
三、小案例:TOP250电影信息(首页)
3.1、requests + bs4
import requests
from bs4 import BeautifulSoup
url = 'https://movie.douban.com/top250'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36 Edg/91.0.864.48'}
res = requests.get(url,headers=headers)
soup = BeautifulSoup(res.text,'lxml')
boxs = soup.select('.info')
for box in boxs:
film_name = box.select('.hd a .title')[0].text
print('电影名称:', film_name, end=' ')
score = box.select('.bd .star .rating_num')[0].text
print('评分:', score, end=' ')
director = box.select('.bd p')[0].text.strip().split('\\n')[0]
print('导演:', director)
结果:
3.2、requests + xpath
import requests
from lxml import etree
url = 'https://movie.douban.com/top250'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36 Edg/91.0.864.48'}
res = requests.get(url,headers=headers)
html = etree.HTML(res.text)
boxs = html.xpath('//div[@class="info"]')
for box in boxs:
film_name = box.xpath('./div/a/span[1]/text()')[0]
print('电影名称:', film_name, end=' ')
score = box.xpath('./div/div/span[2]/text()')[0]
print('评分:', score, end=' ')
director = box.xpath('./div/p/text()')[0].strip()
print('导演:', director)
结果:
以上是关于小爬虫学习——网页解析工具(bs4xpath)的主要内容,如果未能解决你的问题,请参考以下文章