(1)BeautifulSoup :
安装:
pip install lxml
pip install bs4
使用:
from bs4 import beautifulsoup
soup = BeautifulSoup(html, 'lxml') # html是网页文本
p_list = soup.select('p')
- 提供的用于数据解析的方法和属性:
- soup.tagName:返回的是文档中第一次出现的tagName对应的标签(html标签)
- soup.find():
- find('tagName'):等同于soup.div
- 属性定位:
- soup.find('div',class_/id/attr='attrName'):返回符合要求的第一个标签
- soup.find_all('tagName'):返回符合要求的所有标签(列表)
- select:
- select('某种选择器(id,class,标签.·,选择器)·),返回的是一个列表。
- 层级选择器:
- soup.select('.className > ul > li > a'): >表示的是一个层级
- soup.select('.className > ul a'):空格表示的多个层级
- 获取标签之间的文本数据:
- soup.a.text/string/get_text()
- text/get_text():可以获取某一个标签中所有的文本内容
- string:只可以获取该标签下面直系的文本内容
- 获取标签中属性值:
- soup.a['href '
- 环境的安装:
- pip install lxml
- 如何实例化一个etree对象:from lxml import etree
- 1.将本地的htmL文档中的源码数据加载到etree对象中:
etree.parse(filePath)
- 2.可以将从互联网上获取的源码数据加载到该对象中
etree.HTML('page_text')
xpath('xpath表达式')
- xpath表达式【和linux的文件路径操作一样】:
- / : 根节点,节点分隔符,
- // : 任意位置,可以是多个层级
- . 当前节点
- .. 父级节点
- @ 属性定位,如:/div[@class='className'] tag[@attrName="attrValue"]
- 索引定位: //div[@class="className"]/p[3]: 索引是从1开始的
- 取文本:
- /text()获取的是标签中直系的文本内容
- //text()标签中非直系的文本内容(所有的文本内容)
- 取属性:
- /dattrName ==> img/src
爬取国家重点保护野生植物的信息,网站:中国珍稀濒危植物信息系统
import json
from bs4 import BeautifulSoup
from lxml import etree
import requests
import re
def request_url(url):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36',
}
try:
response = requests.get(url, headers = headers)
if response.status_code == 200:
return response.text
except requests.RequestException as e:
print('===>>>请求异常' + e)
return None
def parse_result(html):
"""使用BeautifulSoup进行解析html"""
soup = BeautifulSoup(html, 'lxml')
tr_list = soup.select('tr')
for tr in tr_list:
print("解析结果:" + str(tr))
td_items = tr.select('.td2')
if len(td_items) == 0:
continue
yield {
'中文名': re.sub('\s', '', td_items[0].text),
'拉丁名': re.sub('\s', '', td_items[1].text),
'科名': re.sub('\s', '', td_items[2].text),
'I级': re.sub('\s', '', td_items[3].text),
'II级': re.sub('\s', '', td_items[4].text),
}
def xpath_parse_result(html):
"""使用xpath进行解析html"""
html_doc = etree.HTML(html)
tr_list = html_doc.xpath('//body/form/div[@class="divmenuh"]//table[@class="table1"]//tr')
for tr in tr_list:
print("解析结果:" + str(tr))
td_items = tr.xpath("./td[@class='td2']")
if len(td_items) == 0:
continue
yield {
'中文名': re.sub('\s', '', td_items[0].xpath(".//text()")[0]),
'拉丁名': re.sub('\s', '', td_items[1].xpath(".//text()")[0]),
'科名': re.sub('\s', '', td_items[2].xpath(".//text()")[0]),
'I级': re.sub('\s', '', td_items[3].xpath(".//text()")[0]),
'II级': re.sub('\s', '', td_items[4].xpath(".//text()")[0]),
}
def plant_spider(page):
url = 'http://www.iplant.cn/rep/protlist?page=' + str(page)
html = request_url(url)
if None == html:
print("===>>>请求失败:" + url)
return
items = parse_result(html) # 解析过滤我们想要的信息
# items = xpath_parse_result(html) # 使用xpath进行解析
with open('国家重点保护野生植物(2021版).txt', 'a', encoding='UTF-8') as f:
for item in items:
print('开始写入数据 ====> ' + str(item))
f.write(json.dumps(item, ensure_ascii=False) + '\n')
if __name__ == "__main__":
# 爬取国家重点保护野生植物的信息
for i in range(1, 58):
plant_spider(i)