У меня проблема, я хотел бы знать, стоит ли тратить время на решение с помощью Python. У меня есть большой CSV-файл научных названий рыб. Я хотел бы перекрестно ссылаться на этот файл CSV с большой базой данных о морфологии рыб (www.fishbase.ca) и вернуть код максимальной длины каждой рыбы. В принципе, мне нужно создать код, который будет искать веб-сайт fishbase для каждой рыбы, а затем найти максимальную информацию о нем на странице и вернуть ее мне в CSV-файле. Последние две части относительно просты, но первая часть - это то место, где я застрял. Заранее спасибо.Python Search and Scrape
ответ
Похоже, что вы можете генерировать URL непосредственно из рода и вида, т.е.
радужной форели (Oncorhynchus микижи) становится
http://www.fishbase.ca/summary/Oncorhynchus-mykiss.html
так что-то вроде
def make_url(genus, species):
return (
"http://www.fishbase.ca/summary/{}-{}.html"
.format(genus.title(), species.lower())
)
Глядя источник страницы, html строго неэксантичен; при разборе HTML с использованием регулярных выражений зла и ужасна, я действительно считаю, что это самый простой способ в этом случае:
import re
fishlength = re.compile("max length : ([\d.]+) ([cm]{1,2})", re.I).search
def get_length_in_cm(html):
m = fishlength(html)
if m: # match found
value = float(m.group(1))
unit = m.group(2)
if unit == "cm":
return value
elif unit == "m":
return value * 100.
else:
raise ValueError("Unknown unit: {}".format(unit))
else:
raise ValueError("Length not found")
затем захватывая каждую страницу,
import csv
import requests
from time import sleep
DELAY = 2
GENUS_COL = 4
SPECIES_COL = 5
with open("fish.csv") as inf:
next(inf) # skip header row
for row in csv.reader(inf):
url = make_url(row[GENUS_COL], row[SPECIES_COL])
# should add error handling, in case
# that page doesn't exist
html = requests.get(url).text
length = get_length_in_cm(html)
# now store the length value somewhere
# be nice, don't pound their site
sleep(DELAY)
Я был вдали от этой глубины кодирования более года, поэтому мне нужно будет вернуться к скорости, но похоже, что это может работать для моих нужд, и я действительно ценю помощь. – Jadefox
Таким образом, для использования информации в других веб-приложениях вам необходимо использовать API для получения данных.
У Fishbase.ca (или .org) не было официального API с открытым доступом. Существует около chat in 2013 о создании RESTful API, который будет всего лишь билетом на то, что вам нужно, но этого еще не произошло (не задерживайте дыхание).
Альтернатива - это имя рыбы, которую нужно найти, отбрасывая ее в URI (например, www.fishbase.ca/fish/Rainbow+Trout), а затем используя Xquery или аналогичный, чтобы развернуть DOM, чтобы найти максимальная длина.
К сожалению, у рыбной базы нет такого URI, который необходим для этого метода, либо this является URI для Rainbow Trout - для идентификации можно использовать идентификатор, а не имя.
Я бы предложил изучить другой поставщик данных, ищущий любой из этих двух API.
Что касается второго метода: владельцы сайтов могут не использовать вас на своем веб-сайте таким образом. Спросите их заранее, если сможете.
Это действительно вопрос анализа данных и это трудно сказать что угодно, не видя данных. Один из ключевых вопросов будет заключаться в том, насколько предсказуемо ваши научные имена будут совпадать в обоих наборах данных. Совпадение по свободным текстовым полям часто довольно громоздко, если оба набора не создавались с одинаковыми требованиями/стандартами. Я мог бы начать с выбора дюжины или около того наименований случайным образом из вашего набора и поиска рыбы, установленной, чтобы увидеть, сколько совпадений вы получаете. – dylrei
Спасибо за быстрый ответ. Мой файл CSV выглядит довольно чистым и возвращает хорошие совпадения с сайта fishbase.ca. – Jadefox
Awesome. Это также может быть хорошей задачей для базы данных SQLite. __Update__: не понимал, что у вас нет прямого доступа к набору данных fishbase. Per @gewh, это следующее, что вам нужно учитывать. – dylrei