一、BeautifulSoup
beautifulsoup是一个可以从HTML或Xml文件中提取数据的python库,简单来说,它能将html的标签文件解析成树形结构,然后方便地获取指定标签的对应属性。
通过BeautifulSoup库,我们可以将制定的class或id值作为参数,来直接获取对应标签的相关数据,这样的处理方式简洁明了。
1.四种对象
Tag
Tag 通俗点讲就是 HTML 中的一个个标签,直接用BeautifulSoup来调用
NavigableString
获取标签内部的文字用 .string 即可
BeautifulSoup
BeautifulSoup 对象表示的是一个文档的内容。大部分时候,可以把它当作 Tag对象,是
一个特殊的 Tag,我们可以分别获取它的类型,名称,以及属性
Comment
Comment对象是一个特殊类型的NavigableString 对象,其输出注释但不包含注释符号。
2.方法
2.1 find_all(name, attrs, recursive, text, **kwargs)
- 1)name 参数
name 参数可以查找所有名字为 name 的 tag,字符串对象会被自动忽略掉
A.传字符串
Beautiful Soup会查找与字符串完整匹配的内容
范例:用于查找文档中所有的标签:
print(soup.find\_all('b')) print(soup.find\_all('a'))
B.传正则表达式
Beautiful Soup会通过正则表达式的 match()来匹配内容.
范例:找出所有以 b开头的标签,这表示和标签都应该被找到
import re for tag in soup.find_all(re.compile("^b")): print(tag.name)
C.传列表
Beautiful Soup会将与列表中任一元素匹配的内容返回.
范例:找到文档中所有标签和标签:
print(soup.find_all(["a", "b"]))
- 2)keyword 参数
print(soup.find_all(id='link2'))
- 3)text 参数
text 参数接受字符串,正则表达式,列表, 可以搜搜文档中的字符串内容
print(soup.find_all(text="Elsie"))
print(soup.find_all(text=["Tillie", "Elsie", "Lacie"]))
print(soup.find_all(text=re.compile("Dormouse")))
2.2 CSS选择器 (重点!!!!!!)
写 CSS时,标签名不加任何修饰,类名前加.,id名前加#
可以利用类似的 soup.select()方法来筛选元素,返回结果是 list
soup.select_one() 返回值是list的首个。
- (1)通过标签名查找
print(soup.select('title')) print(soup.select('a')) 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 #link1')) 直接子标签查找,则使用 > 分隔
print(soup.select("head > title")
+(5)属性查找
查找时还可以加入属性元素,属性需要用中括号括起来,注意属性和标签属于同一节点,
所以中间不能加空格,否则会无法匹配到。
print(soup.select('a[class="sister"]'))
print(soup.select('a[href="http://example.com/elsie"]'))
同样,属性仍然可以与上述查找方式组合,不在同一节点的空格隔开,同一节点的不加
空格
print(soup.select('p a[href="http://example.com/elsie"]'))
- (6)获取内容
可以遍历 select 方法返回的结果,然后用 get_text() 方法来获取它的内容。
soup = BeautifulSoup(html, 'lxml')
print(type(soup.select('title')))
print(soup.select('title')[0].get_text())
for title in soup.select('title'):
print(title.get_text())
3 实战
import urllib.request
from bs4 import BeautifulSoup as bs
def getItem(html):
datas = [] # 用来存放获取的用户名和评论
for data in html.find_all("tbody"):
try:
userid = data.find("div", class_="auth").get_text(strip=True)
print(userid)
content = data.find("td", class_="postbody").get_text(strip=True)
print(content)
datas.append((userid,content))
except:
pass
print(datas)
def main():
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"
}
url = 'http://www.dxy.cn/bbs/thread/626626'
request = urllib.request.Request(url, headers=headers)
response = urllib.request.urlopen(request).read().decode("utf-8")
html = bs(response, 'lxml')
getItem(html)
if __name__ == '__main__':
main()
二、Xpath
XPath的选择功能十分强大,它提供了非常简洁明了的路径选择表达式。另外,它还提供了超过100个内建函数,用于字符串、数值、时间的匹配以及节点、序列的处理等。几乎所有我们想要定位的节点,都可以用XPath来选择。
1.实战
from lxml import etree
import requests
def get_html(url, headers):
response = requests.get(url, headers = headers)
try:
if response.status_code == 200:
return response.text
except:
pass
def get_parse(html):
tree = etree.HTML(html)
user = tree.xpath('//*/table/tbody/tr/td/div/a/text()')
reply = tree.xpath('//*/table/tbody/tr/td/div/div/table/tbody/tr/td/text()')
for users, replys in zip(user, reply):
print('用户名:\n'+users+"\n", '回复内容:\n'+ replys.strip()+"\\")
def main():
url = 'http://www.dxy.cn/bbs/thread/626626'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'
}
html = get_html(url, headers)
get_parse(html)
if __name__ == '__main__':
main()