我有一个问题想知道是否值得花时间尝试用 Python 来解决。我有一个包含鱼类学名的大型 CSV 文件。我想将该 CSV 文件与大型鱼类形态信息数据库 (www.fishbase.ca) 交叉引用,并让代码返回每条鱼的最大长度。基本上,我需要创建代码来搜索 Fishbase 网站上的每条鱼,然后找到页面上的最大长度信息并以 CSV 文件将其返回给我。最后两部分相对简单,但第一部分是我陷入困境的地方。提前致谢。
当然可以,抓取 FishBase 来获取鱼类的最大长度信息是绝对可行的。方法如下:
1. 导入必要的库
import csv
import requests
from bs4 import BeautifulSoup
2. 创建函数来从 FishBase 中提取最大长度
def get_max_length(scientific_name):
"""从 FishBase 中获取给定鱼类的最大长度。
Args:
scientific_name: 鱼类的学名(str)。
Returns:
最大长度(str),如果没有找到则返回 None。
"""
# 将学名格式化为 FishBase URL
url = f"https://www.fishbase.ca/summary/{scientific_name.replace(' ', '-')}.html"
try:
# 获取网页内容
response = requests.get(url)
response.raise_for_status() # 如果请求失败,则引发异常
# 使用 BeautifulSoup 解析 HTML 内容
soup = BeautifulSoup(response.content, 'html.parser')
# 找到包含最大长度的表格行
max_length_row = soup.find('td', string='Maximum Length').find_next_sibling('td')
# 从表格行中提取最大长度
max_length = max_length_row.text.strip()
return max_length
except requests.exceptions.RequestException as e:
print(f"无法获取 {scientific_name} 的数据:{e}")
return None
3. 读取 CSV 文件并处理每行
# CSV 文件的路径
csv_file = 'fish_names.csv'
# 存储结果的列表
results = []
# 使用 'utf-8' 编码读取 CSV 文件来处理特殊字符
with open(csv_file, 'r', encoding='utf-8') as file:
reader = csv.reader(file)
# 跳过标题行(如果有)
next(reader, None)
for row in reader:
scientific_name = row[0] # 假设学名在第一列
max_length = get_max_length(scientific_name)
# 将结果存储在一个列表中,即使最大长度为 None
results.append([scientific_name, max_length])
# 将结果写入新的 CSV 文件
with open('fish_max_lengths.csv', 'w', newline='', encoding='utf-8') as file:
writer = csv.writer(file)
writer.writerow(['Scientific Name', 'Maximum Length']) # 写入标题行
writer.writerows(results)
此代码将执行以下操作:
-
读取
的 CSV 文件,并将每个学名传递给
get_max_length
函数。 -
get_max_length
函数: - 根据给定的学名 构建 FishBase URL 。
- 获取 FishBase 页面。
- 使用 Beautiful Soup 解析 HTML 内容。
- 查找 包含“最大长度”的特定表格单元格,并 提取 最大长度值。
- 返回 最大长度。
- 将 学名和提取的最大长度 写入 一个新的 CSV 文件。
重要提示:
- 在抓取网站之前, 请务必检查其使用条款 。
- 网站的结构可能会发生变化,因此可能需要相应地 调整代码 。
- 如果抓取过程发送大量请求,请考虑在请求之间 添加延迟 ,以避免给服务器造成过大的负载。
此脚本可以帮助从 FishBase 中提取鱼类的最大长度信息。
标签:python,web-scraping,search From: 28028327