#python #web-scraping #beautifulsoup
Вопрос:
Я пытаюсь очистить веб-сайт Bulbapedia (вики о покемонах), чтобы создать какой-то Pokedex на Python, используя BeaufiulSoup4. Мне интересно, как создать функции, которые будут высасывать данные из html.
У меня есть начальная функция, которая принимает URL-адрес и изменяет его на объект супа:
def urlToSoup(url):
website = requests.get(url)
soup = BeautifulSoup(website.text,'html.parser')
return soup
Что дальше — я хочу получить подробную информацию о покемонах с данного веб-сайта. Допустим, у меня есть Бульбасавр. Я могу создать одну огромную функцию, чтобы получить эти сведения и вернуть серию панд:
def getPokemonDetails(pokemon):
#Get pokemon HTML
URL = 'https://bulbapedia.bulbagarden.net/wiki/' pokemon '_(Pokémon)'
soup = urlToSoup(URL)
#Get pokemon number
number = int(soup.select('big>a[title="List of Pokémon by National Pokédex number"]')[0].text[1:])
#Get pokemon name
name = soup.select('big>b')[0].text
.
.
.
return pd.Series(
data=[
number,
name,
category,
name_JP,
...
],
index=[
'number',
'name',
'category',
'japanese_name',
...
]
)
Точки просто говорят вам, что есть еще код, но дело не в этом. Выше вы видите, как я в настоящее время храню свой код. На мой взгляд, форма плоха, потому что каждая отдельная функция, такая как «Получить номер поэмона», «Получить имя поэмона» и т. Д., Должна обрабатываться разными функциями.
Моя первая идея состояла в том, чтобы создать одну функцию для каждой функции, где в качестве аргумента вы передаете имя покемона, например «Бульбасаур». Проблема здесь в том, что, когда я хочу собрать всю информацию о данном покемоне, каждая функция будет запрашивать HTML, анализировать его до супа, а это отнимает много времени. Получите имя, номер, возраст, рост и т.д. будет запущена функция urlToSoup, которая неэффективна.
def getNumber(pokemon)
soup = urlToSoup(https://bulbapedia.bulbagarden.net/wiki/' pokemon '_(Pokémon))
somecodetogetnumber
return number
def getName(pokemon)
soup = urlToSoup(https://bulbapedia.bulbagarden.net/wiki/' pokemon '_(Pokémon))
somecodetogetname
return name
.
.
.
Поэтому я подумал, что вместо передачи имени покемона и повторного вызова функции «urlToSoup» я вызову ее один раз, чтобы получить суп для данного поэмона, и передам это в качестве аргумента для getName, getNumber, getWeight и т. Д.
def getNumber(pokemon_soup)
somecodetogetnumber
return number
def getName(pokemon_soup)
somecodetogetname
return name
.
.
.
def getPokemonDetails(pokemon)
URL = 'https://bulbapedia.bulbagarden.net/wiki/' pokemon '_(Pokémon)'
soup = urlToSoup(URL)
number = getNumber(soup)
name = getName(soup)
Но вопрос в том, если я создам суп для данного покемона и передам его в качестве аргумента функции, будут ли функции создавать копию супа для работы или будет только один бульбасавровый суп, над которым будут работать все функции (при условии, что я передам этот бульбасавровый суп в качестве аргумента). Другими словами, если я создам суп для данного покемона и передам его функции, будет ли он передаваться по ссылке на суп или сделает копию? Во втором случае это все равно неэффективно.
Я надеюсь, что вы ясно видите, каковы мои идеи, и можете посоветовать мне, что делать.
Комментарии:
1. Очистка веб-страниц с помощью Beautiful Soup требует разных сценариев и логики для разных веб-сайтов, основанных на информации, которую мы пытаемся очистить. Будет здорово, если вы сможете указать все, что вам нужно, и точный URL-адрес для этой страницы.
2. Вот пример URL -адреса bulbapedia.bulbagarden.net/wiki/Bulbasaur_(Pokémon) , хотя имейте в виду, что я буду просматривать все 900 URL-адресов с покемонами. К счастью, структура для каждого URL-адреса одинакова. Программа будет просматривать разные места, такие как таблица, в которой указаны типы покемонов, их количество, вес и т.д. Вот почему я думаю, что мне следует сохранить их в разных функциях
Ответ №1:
Функция не создаст копию, если в качестве аргумента указан суп, рассмотрим следующий простой пример:
from bs4 import BeautifulSoup
def change_soup_name(s, n):
s.name = n
soup = BeautifulSoup('<html><head></head><body></body></html>', 'html.parser')
print(soup.name)
change_soup_name(soup, '[newname]')
print(soup.name)
выход
[document]
[newname]
Комментарии:
1. Так что, похоже, я могу использовать функции, передавая суп 🙂 Спасибо