Как управлять функциями, чтобы эффективно использовать красивый суп

#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. Так что, похоже, я могу использовать функции, передавая суп 🙂 Спасибо