爬虫常用解析库bs4 xpath常见用法

BeautifSoup4

初始化方法

resp = requests.get('https://www.baidu.com/',headers=header)
resp.encoding='utf-8'
soup = BeautifulSoup(resp.text,'lxml')
print(soup.prettify())

解析器

格式化html

子节点

 

 父节点

.parent 获取直接父节点

.parents 获取祖先结点

兄弟结点

.next_sibling获取下一个兄弟节点

.previous_sibling获取上一个兄弟节点

.previous_siblings获取上一个所有兄弟节点

以上方法获取多个结点时,换行会截断

定位

使用标签名定位标签

这种方法只能定位第一个该标签名对应的标签

PS:提取标签内的文本信息 使用标签对象.string或 标签对象.text

两者区别:如果string标签内还有其他的标签,使用string会提取出None,而使用text会将标签内中的全部标签的文本提取出来

获取标签内属性:全部属性 object.attrs 指定属性 object['属性名']或 object.get("属性名")

find方法

find( name , attrs , recursive , string , **kwargs )

find_all() 方法将返回文档中符合条件的所有tag,尽管有时候我们只想得到一个结果.比如文档中只有一个<body>标签,那么使用 find_all() 方法来查找<body>标签就不太合适, 使用 find_all 方法并设置 limit=1 参数不如直接使用 find() 方法.

findall方法

find_all( name , attrs , recursive , string , **kwargs )

find_all() 方法搜索当前tag的所有tag子节点,并判断是否符合过滤器的条件.这里有几个例子:

soup.find_all("title")
# [<title>The Dormouse's story</title>]

soup.find_all("p", "title")
# [<p class="title"><b>The Dormouse's story</b></p>]

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>]

soup.find_all(id="link2")
# [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]

import re
soup.find(string=re.compile("sisters"))
# u'Once upon a time there were three little sisters; and their names were\n'

有几个方法很相似,还有几个方法是新的,参数中的 string 和 id 是什么含义? 为什么 find_all("p", "title") 返回的是CSS Class为”title”的<p>标签? 我们来仔细看一下 find_all() 的参数

name 参数

name 参数可以查找所有名字为 name 的tag,字符串对象会被自动忽略掉.

简单的用法如下:

soup.find_all("title")

keyword 参数

如果一个指定名字的参数不是搜索内置的参数名,搜索时会把该参数当作指定名字tag的属性来搜索,如果包含一个名字为 id 的参数,Beautiful Soup会搜索每个tag的”id”属性.

soup.find_all(id='link2')
# [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]

如果传入 href 参数,Beautiful Soup会搜索每个tag的”href”属性:

soup.find_all(href=re.compile("elsie"))
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]

搜索指定名字的属性时可以使用的参数值包括 字符串 , 正则表达式 , 列表True .

下面的例子在文档树中查找所有包含 id 属性的tag,无论 id 的值是什么:

soup.find_all(id=True)
# [<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>]

使用多个指定名字的参数可以同时过滤tag的多个属性:

soup.find_all(href=re.compile("elsie"), id='link1')
# [<a class="sister" href="http://example.com/elsie" id="link1">three</a>]

但是可以通过 find_all() 方法的 attrs 参数定义一个字典参数来搜索包含特殊属性的tag:

data_soup.find_all(attrs={"data-foo": "value"})
# [<div data-foo="value">foo!</div>]

PS:搜索class时要用class_ 

CSS选择器

选择所有出现的标签的列标

soup.select("title")

获取第一各结点:soup.select("title")[0]

选择第一个出现的指定标签

soup.select_one("title")

获取标签的属性,soup.select_one("title")['herf'] 

获取内容,soup.select_one("title").text,注意这样获取到的是子节点中全部的text,空格也算一个

通过CSS的类名查找:

soup.select(".sister")
# [<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>]

soup.select("[class~=sister]")
# [<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>]

PS:若类值中有空格则需要使用.来链式调用

通过tag的id查找:

符合标签a然后又有属性link2  =》  a#link2

符合标签a又有属性link2 =》a.link2

soup.select("#link1")
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]

soup.select("a#link2")
# [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]

同时用多种CSS选择器查询元素:

soup.select("#link1,#link2")
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
#  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]

通过是否存在某个属性来查找:

soup.select('a[href]')
# [<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>]

通过属性的值来查找:

^匹配开始位置
$匹配结束位置
*匹配任意字符

soup.select('a[href="http://example.com/elsie"]')
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]

soup.select('a[href^="http://example.com/"]')
# [<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>]

soup.select('a[href$="tillie"]')
# [<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

soup.select('a[href*=".com/el"]')
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]

逐层搜索用>声明,找前后结点(考虑结点关系)

 逐层搜索用空格声明,找前后结点(不考虑结点关系)

 搜索兄弟结点用~声明,找前后结点(不考虑结点关系)

 

 xpath

初始化

from lxml import etree
import requests
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
}
resp = requests.get('https://www.baidu.com/',headers=header)
resp.encoding='utf-8'
res_xpath = etree.HTML(resp.text)

知识点

查找

res_xpath = etree.HTML(resp.text)
//绝对路径
title_object = res_xpath.xpath('/html/head/title')//获取全部title标签对象,类型为list
//任意路径
title_object = res_xpath.xpath('//title')//获取全部title标签对象,类型为list
print(title_object.xpath('text()'))//获取标签内文本信息

按照属性

提取有herf属性的a标签

a[@herf]

提取class属性值为123的a标签

a[@class="123"]

可以加多个属性

a[@class="123" and @herf="hhhh"]

提取

提取文本 text()

title_object = res_xpath.xpath('//title')//获取全部title标签对象,类型为list
print(title_object.xpath('text()'))//获取标签内文本信息

提取属性

title_object = res_xpath.xpath('//title')//获取全部title标签对象,类型为list
print(title_object.xpath('@href'))//获取标签内href属性

从当前结点下查找

title_object = res_xpath.xpath('//title')//获取全部title标签对象,类型为list
hhh = title_object('//hhh/text()')

获取兄弟结点

./following-sibling::兄弟标签名[1]  下面一个兄弟节点

./following-sibling::*[N]    下面N个性的节点

./preceding-sibling::兄弟标签名[1]    上面一个兄弟节点

./following-sibling::*[N]     上面N个性的节点

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python爬虫中的bs4和xpath是两种常用的数据提取工具。 bs4(Beautiful Soup 4)是一个基于Python的,用于解析HTML和XML文档。它能够帮助我们从网页中提取数据并进行处理。bs4提供了一些简单且易于使用的方法,例如通过标签名、类名、属性等进行查找和筛选数据。 下面是一个简单的使用bs4进行数据提取的例子: ```python from bs4 import BeautifulSoup import requests # 发送HTTP请求获取页面内容 url = "http://example.com" response = requests.get(url) html_content = response.content # 使用bs4解析页面内容 soup = BeautifulSoup(html_content, 'html.parser') # 提取数据 title = soup.title.text print("网页标题:", title) # 查找某个标签并获取其文本内容 h1 = soup.find("h1") print("h1标签内容:", h1.text) # 查找所有的链接并输出链接文本和URL links = soup.find_all("a") for link in links: print("链接文本:", link.text) print("链接URL:", link["href"]) ``` 另一方面,XPath是一种用于选择XML文档中节点的语言。在爬虫中,我们可以使用XPath来从HTML或XML文档中提取数据。XPath提供了强大且灵活的选择器,可以使用路径表达式来定位节点。 下面是一个使用XPath进行数据提取的示例: ```python import requests from lxml import etree # 发送HTTP请求获取页面内容 url = "http://example.com" response = requests.get(url) html_content = response.content # 使用lxml解析页面内容 tree = etree.HTML(html_content) # 提取数据 title = tree.xpath("//title/text()")[0] print("网页标题:", title) # 查找某个标签并获取其文本内容 h1 = tree.xpath("//h1/text()")[0] print("h1标签内容:", h1) # 查找所有的链接并输出链接文本和URL links = tree.xpath("//a") for link in links: link_text = link.xpath("text()")[0] link_url = link.xpath("@href")[0] print("链接文本:", link_text) print("链接URL:", link_url) ``` 以上就是使用bs4和XPath进行数据提取的示例代码。希望能帮助到你!如有需要,请随时追问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值