一、BeaulifulSoup4--解析和提取XML/HTML数据
1. BeautifulSoup4简介
BeautifulSoup4和 lxml 一样,Beautiful Soup 也是一个HTML/XML的解析器,主要的功能也是如何解析和提取 HTML/XML 数据。
lxml 只会局部遍历,而Beautiful Soup 是基于HTML DOM的,会载入整个文档,解析整个DOM树,因此时间和内存开销都会大很多,所以性能要低于lxml。
抓取工具 | 速度 | 使用难度 | 安装难度 |
正则 | 最快 | 困难 | 无(内置) |
BeautifulSoup | 慢 | 最简单 | 简单 |
lxml | 快 | 简单 | 一般 |
2. Python3中Linux安装命令:sudo pip3 install beautifulsoup4
官方文档:http://beautifulsoup.readthedocs.io/zh_CN/v4.4.0
3. 语法
3.1 find_all
#创建 Beautiful Soup 对象
soup = BeautifulSoup(html,"lxml")
# 参数可以是字符串
list1 = soup.find_all(name="p")
# 参数可以是列表
list2 = soup.find_all(["a","p"])
# 参数可以是正则
list3 = soup.find_all(re.compile("^p"))
# keyword参数 查找id为link的标签
soup.find_all(id='link')
# text 参数接受 字符串 , 正则表达式 , 列表
import re
print(soup.find_all(text="Elsie"))
# []
print(soup.find_all(text=["Tillie", "Elsie", "Lacie"]))
# ['Lacie', 'Tillie']
# 查找包含’Dormouse’内涵的
print(soup.find_all(text=re.compile("Dormouse")))
# 得到所有的匹配的href链接
links = soup.find_all(href=re.compile(r'http://example.com/'))
3.2. 选择器(select)-用得多
这就是另一种与 find_all 方法有异曲同工之妙的查找方法.
写 CSS 时,标签名不加任何修饰,类名前加.,id名前加#
# 根据标签名
print(soup.select('title'))
# 根据类名
print(soup.select('.sister'))
# 根据id
print(soup.select('#link1'))
# 根据组合
print(soup.select('p #link1'))
item = soup.select("#mainsrp-itemlist .items .item") # 多个标签类名,空格隔开
image = item.select('.J_ItemPic.img')[0].attrs["data-src"] # 类名
# 根据属性
print(soup.select('a[class="sister"]'))
print(soup.select('p a[href="http://example.com/elsie"]'))
以上的 select 方法返回的结果都是列表形式,可以遍历形式输出,然后用 get_text() / text 方法来获取它的内容
print(type(soup.select('title')))
print(soup.select('title')[0].get_text())
print(soup.select('title')[0].text)
for title in soup.select('title'):
print(title.get_text())
4 . 使用beautifulsoup4爬取腾讯社招招聘信息
import requests
from bs4 import BeautifulSoup
#抓取腾讯的社招招聘信息
def tencent():
url = "https://hr.tencent.com/position.php?&start=10"
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36"
}
response = requests.get(url,headers=headers)
html = response.content
soup = BeautifulSoup(html,"lxml")
even_soup = soup.select('tr[class="even"]')
# print(even_soup)
odd_soup = soup.select('tr[class="odd"]')
resul_data = even_soup + odd_soup
#名称(name)、连接(data_link)、职位类别(job_category)、
# 招聘人数( recruit_number)、工作地点(address)、发布时间(publish_time)
items = []
for data in resul_data:
item = {}
name = data.a.string
data_link = data.a.attrs['href']
job_category = data.select('td')[1].get_text()
recruit_number = data.select("td")[2].get_text()
address = data.select("td")[3].get_text()
publish_time = data.select("td")[4].get_text()
#添加到字典里面
item["name"] = name
item["data_link"] = data_link
item["job_category"] = job_category
item["recruit_number"] = recruit_number
item["address"] = address
item["publish_time"] = publish_time
#把字典添加到列表里面
items.append(item)
print(items)
with open("json.txt","w") as f:
f.write(str(items))
if __name__ == "__main__":
tencent()