目录
- 一、数据解析利器——beautifulsoup
- 1.1 安装
- 1.2 安装解析器
- 1.3 快速使用:
- 1.4 获取标签内容相关方法:
- 1.4.1 .content、.strings和.text
- 1.4.1.1 相同点与区别:
- 1.4.1.2 使用示例:
- 1.4.2 .string
-
- 1.4.3 .stripped_strings
-
- 1.5 搜索相关方法:
- 1.5.1 find_all方法
- 1.5.1.1 使用场景及示例:
- 1.5.1.2 传入参数解析:
- 1.6 css选择器
- 二、数据解析利器——xpath
- 2.1、xpath安装 pip install lxml
- 2.2、快速使用
- 2.3、xpath语法
- 2.3.1、路径表达式:
- 2.3.2、谓语(Predicates):
- 2.3.3、选取未知节点:
- 2.3.4、选取若干路径:
- 2.3.5、逻辑运算
- 2.3.6、属性查询
- 2.3.7、查询相关
- 2.3.8、获取节点内容转换成字符串
一、数据解析利器——beautifulsoup
1.1 安装
pip install beautifulsoup4
1.2 安装解析器
Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,如果我们不安装它,则 Python 会使用 Python默认的解析器,lxml 解析器更加强大,速度更快,推荐安装。
安装方式:python pip install lxml
1.3 快速使用:
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'lxml')
print(soup.prettify())
soup.title soup.title.name soup.title.string soup.title.parent soup.title.parent.name soup.p soup.p['class'] soup.a soup.find_all('a') soup.find(id="link3")
1.4 获取标签内容相关方法:
1.4.1 .content、.strings和.text
1.4.1.1 相同点与区别:
.content、.strings和.text方法都可以返回标签内所有的文本内容,区别在于.content返回列表,.strings返回生成器,.text返回字符串
1.4.1.2 使用示例:
head_tag = soup.head
head_tag.contents
head_tag.strings
head_tag.textfor string in soup.strings:print(repr(string))
title_tag = head_tag.contents[0]
1.4.2 .string
1.4.2.1 使用场景:
如果标签里面没有标签了,那么 .string 就会返回标签里面的内容。
如果标签里面只有唯一的一个标签了,那么 .string 也会返回最里面的内容。
如果标签里面包含了多个子标签,.string 的输出结果是 None
1.4.3 .stripped_strings
1.4.3.1 使用场景:
输出的字符串中可能包含了很多空格或空行,使用 `.stripped_strings`可以去除多余空白内容for string in soup.stripped_strings:print(repr(string))
1.5 搜索相关方法:
1.5.1 find_all方法
1.5.1.1 使用场景及示例:
`find_all()` 方法搜索当前标签的所有子标签,并判断是否符合过滤器的条件
soup.find_all("title")
soup.find_all("p", "title")
soup.find_all("a")
soup.find_all(id="link2")
import re
soup.find_all(string=re.compile("sisters"))
1.5.1.2 传入参数解析:
1、name参数解析:`name` 参数可以查找所有名字为 `name` 的标签,字符串对象会被自动忽略掉`name` 参数的值可以是字符串,正则表达式,列表,方法或是 `True`传入字符串:最简单的过滤器是字符串.在搜索方法中传入一个字符串参数,Beautiful Soup会查找与字符串完整匹配的内容下面的例子用于查找文档中所有的<b>标签:soup.find_all('b')传入正则表达式:如果传入正则表达式作为参数,Beautiful Soup会通过正则表达式的 `match()` 来匹配内容.下面例子中找出所有以b开头的标签,这表示\<body>和\<b>标签都应该被找到:import refor tag in soup.find_all(re.compile("^b")):print(tag.name)传列表:如果传入列表参数,Beautiful Soup会将与列表中任一元素匹配的内容返回下面代码找到文档中所有\<a>标签和\<b>标签:soup.find_all(["a", "b"])2、keyword 参数解析:如果一个指定名字的参数不是搜索内置的参数名,搜索时会把该参数当作指定名字tag的属性来搜索比如如果包含一个名字为 `id` 的参数,Beautiful Soup会搜索每个标签的”id”属性:soup.find_all(id='link2')其他示例:import reprint(soup.find_all(href=re.compile("elsie")))print(soup.find_all(text=re.compile("^The")))使用多个指定名字的参数可以同时过滤tag的多个属性:soup.find_all(href=re.compile("elsie"), id='link1')如果我们想用 class 过滤,不过 class 是 python 的关键词,需要加个下划线:print(soup.find_all("a", class_="sister"))3、attrs 参数解析:通过`attrs` 参数定义一个字典参数来搜索包含特殊属性的tag:data_soup.find_all(attrs={"data-foo": "value"})注意:如何查看条件id和class同时存在时的写法print(soup.find_all('b', class_="story", id="x"))print(soup.find_all('b', attrs={"class":"story", "id":"x"}))4、text 参数解析:通过 `text` 参数可以搜搜文档中的字符串内容:print(soup.find_all(text=re.compile("Dormouse")))5、limit 参数解析:`find_all()` 方法返回全部的搜索结构,如果文档树很大那么搜索会很慢如果我们不需要全部结果,可以使用 `limit` 参数限制返回结果的数量:print(soup.find_all("a",limit=2))
1.6 css选择器
1、通过标签名查找print(soup.select("title")) print(soup.select("b")) 2、通过类名查找print(soup.select(".sister"))3、通过id名查找print(soup.select("#link1"))4、组合查找组合查找和写 class 文件时,标签名与类名、id名进行的组合原理是一样的例如查找 p 标签中,id 等于 link1的内容,二者需要用空格分开print(soup.select("p #link2"))5、直接子标签查找print(soup.select("p > #link2"))6、查找既有class也有id选择器的标签a_string = soup.select(".story#test")7、查找有多个class选择器的标签a_string = soup.select(".story.test")8、查找有多个class选择器和一个id选择器的标签a_string = soup.select(".story.test#book")9、属性查找查找时还可以加入属性元素,属性需要用中括号括起来注意属性和标签属于同一节点,所以中间不能加空格,否则会无法匹配到。print(soup.select("a[href='http://example.com/tillie']"))10、select 方法返回的结果都是列表形式,可以遍历形式输出,然后用 get_text() 方法来获取它的内容:for title in soup.select('a'):print (title.get_text())
二、数据解析利器——xpath
2.1、xpath安装 pip install lxml
2.2、快速使用
html_tree = etree.HTML(html字符串)html_tree.xpath()使用xpath路径查询信息,返回一个列表
2.3、xpath语法
2.3.1、路径表达式:
| / | 从根节点选取。 || // | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 || ./ | 当前节点再次进行xpath || @ | 选取属性。 |在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:| /html | 选取根元素。 || //li | 选取所有li 子元素,而不管它们在文档中的位置。 || //ul//li | 选择属于 ul元素的后代的所有 li元素,而不管它们位于 ul之下的什么位置。 || 节点对象.xpath('./div') | 选择当前节点对象里面的第一个div节点 || //@href | 选取名为 href 的所有属性。 |
2.3.2、谓语(Predicates):
谓语用来查找某个特定的节点或者包含某个指定的值的节点。谓语被嵌在方括号中。在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:| 路径表达式 | 结果 || /ul/li[1] | 选取属于 ul子元素的第一个 li元素。 || /ul/li[last()] | 选取属于 ul子元素的最后一个 li元素。 || /ul/li[last()-1] | 选取属于 ul子元素的倒数第二个 li元素。 || //ul/li[position()<3] | 选取最前面的两个属于 ul元素的子元素的 li元素。 || //a[@title] | 选取所有拥有名为 title的属性的 a元素。 || //a[@title='xx'] | 选取所有 a元素,且这些元素拥有值为 xx的 title属性。 || //a[@title>10] `> < >= <= !=` | 选取 a元素的所有 title元素,且其中的 title元素的值须大于 10。 || /bookstore/book[price>35.00]/title | 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。 |
2.3.3、选取未知节点:
XPath 通配符可用来选取未知的 XML 元素。| 通配符 | 描述 || * | 匹配任何元素节点。 一般用于浏览器copy xpath会出现 || @* | 匹配任何属性节点。 || node() | 匹配任何类型的节点。 |在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:| 路径表达式 | 结果 || /ul/* | 选取 ul元素的所有子元素。 || //* | 选取文档中的所有元素。 || //title[@*] | 选取所有带有属性的 title 元素。 || //node() | 获取所有节点 |
2.3.4、选取若干路径:
通过在路径表达式中使用“|”运算符,您可以选取若干个路径。在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:| 路径表达式 | 结果 || //book/title | //book/price | 选取 book 元素的所有 title 和 price 元素。 || //title | //price | 选取文档中的所有 title 和 price 元素。 || /bookstore/book/title | //price | 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。 |
2.3.5、逻辑运算
查找所有id属性等于head并且class属性等于s_down的div标签//div[@id="head" and @class="s_down"]选取文档中的所有 title 和 price 元素。//title | //price注意: “|”两边必须是完整的xpath路径
2.3.6、属性查询
查找所有包含id属性的div节点//div[@id]查找所有id属性等于maincontent的div标签//div[@id="maincontent"]查找所有的class属性//@class获取li标签中name为xx的里面的文本内容//li[@name="xx"]//text()
2.3.7、查询相关
查询所有id属性中包含he的div标签//div[contains(@id, "he")]查询所有id属性中包以he开头的div标签//div[starts-with(@id, "he")]查找所有div标签下的直接子节点h1的内容//div/h1/text()
2.3.8、获取节点内容转换成字符串
c = tree.xpath('//li/a')[0]result=etree.tostring(c, encoding='utf-8')print(result.decode('UTF-8'))