Bs4-подход к странице википедии: получение информационного окна

в настоящее время я пытаюсь применить подход bs4 к странице википедии: результаты не сохраняются в df

из-за того, что парсинг в Википедии является очень распространенным методом, при котором мы можем использовать подходящий подход для работы со многими разными заданиями, у меня были некоторые проблемы с возвратом результатов и сохранением их в df.

ну, в качестве примера очень распространенного задания Wikipedia-bs4, мы можем взять вот это:

на этой странице у нас есть более 600 результатов - на подстраницах: url = "https://de.wikipedia.org/wikiListe_der_St%C3%A4dte_in_Deutschland#Liste_der_St%C3%A4dte_in_Deutschland"

Итак, чтобы создать первый экспериментальный сценарий, я следую следующим образом: сначала я очищаю таблицу со страницы Википедии, а затем конвертирую ее в DataFrame Pandas. Поэтому я сначала устанавливаю необходимые пакеты: убедитесь, что у вас установлены запросы, beautifulsoup4 и pandas. Вы можете установить их с помощью pip, если вы еще этого не сделали:

Pip запрашивает установку beautifulsoup4 pandas

а затем я делаю следующее: сначала я очищаю таблицу со страницы Википедии, а затем конвертирую ее в DataFrame Pandas.

import pandas as pd

# URL of the Wikipedia page
url = "https://de.wikipedia.org/wiki/Liste_der_St%C3%A4dte_in_Deutschland#Liste_der_St%C3%A4dte_in_Deutschland"
table = pd.read_html(url, extract_links='all')[1]
base_url = 'https://de.wikipedia.org'
table = table.apply(lambda col: [v[0] if v[1] is None else f'{base_url}{v[1]}' for v in  col])


links = list(table.iloc[:,0])

for link in links:
    print('\n',link)
    try:
        df = pd.read_html(link)[0]
        print(df)
    except Exception as e:
        print(e)

посмотрим, что я получу в ответ — всего две записи. вместо сотен. кстати; Я думаю, что лучший способ — собрать все в df. и &/или сохранить его

Document is empty

 https://de.wikipedia.org/wiki/Aach_(Hegau)
                                       Wappen  \
0                                         NaN   
1                                         NaN   
2                                  Basisdaten   
3                                Koordinaten:   
4                                 Bundesland:   
5                           Regierungsbezirk:   
6                                  Landkreis:   
7                                       Höhe:   
8                                     Fläche:   
9                                  Einwohner:   
10                        Bevölkerungsdichte:   
11                              Postleitzahl:   
12                                   Vorwahl:   
13                           Kfz-Kennzeichen:   
14                         Gemeindeschlüssel:   
15                                    LOCODE:   
16              Adresse der  Stadtverwaltung:   
17                                   Website:   
18                             Bürgermeister:   
19  Lage der Stadt Aach im Landkreis Konstanz   
20                                      Karte   

                                     Deutschlandkarte  
0                                                 NaN  
1                                                 NaN  
2                                          Basisdaten  
3   47° 51′ N, 8° 51′ OKoordinaten: 47° 51′ N, 8° ...  
4                                   Baden-Württemberg  
5                                            Freiburg  
6                                            Konstanz  
7                                        545 m ü. NHN  
8                                           10,68 km2  
9                             2384 (31. Dez. 2022)[1]  
10                               223 Einwohner je km2  
11                                              78267  
12                                              07774  
13                                            KN, STO  
14                                        08 3 35 001  
15                                             DE AAC  
16                         Hauptstraße 16  78267 Aach  
17                                        www.aach.de  
18                                     Manfred Ossola  
19          Lage der Stadt Aach im Landkreis Konstanz  
20                                              Karte 

примечание: у нас там несколько сотен записей:

см. информационное окно: я хочу получить данные информационного окна

обновление: на что направлено: - как получить полные результаты - которые хранятся в файле df. - и содержащий все данные - в поле info.. (см. изображение выше) - с контактной информацией и т. д.

обновление2:

обзор - страница: https://de.wikipedia.org/wiki/Liste_der_St%C3%A4dte_in_Deutschland#Liste_der_St%C3%A4dte_in_Deutschland

это приведет нас примерно к 1000 подстраницам: как показано ниже

Аах (Хегау): https://de.wikipedia.org/wiki/Aach_(Хегау) Ахен: https://de.wikipedia.org/wiki/Аахен Аален: https://de.wikipedia.org/wiki/Аален

увидеть результат так называемого «информационного окна»: https://de.wikipedia.org/wiki/Babenhausen_(Hessen) Бабенхаузен (Гессен)

+----------------------+--------------------------------------------------------------+
|                      |                                                              |
+----------------------+--------------------------------------------------------------+
| koordinaten:         | ♁49° 58′ N, 8° 57′ OKoordinaten: 49° 58′ N, 8° 57′ O | | OSM |
| Bundesland:          | Hessen                                                       |
| Regierungsbezirk:    | Darmstadt                                                    |
| Landkreis:           | Darmstadt-Dieburg                                            |
| Höhe:                | 124 m ü. NHN                                                 |
| Fläche:              | 66,85 km2                                                    |
| Einwohner:           | 17.579 (31. Dez. 2023)[1]                                    |
| Bevölkerungsdichte:  | 263 Einwohner je km2                                         |
| Postleitzahl:        | 64832                                                        |
| Vorwahl:             | 06073                                                        |
| Kfz-Kennzeichen:     | DA, DI                                                       |
| Gemeindeschlüssel:   | 06 4 32 002                                                  |
| Stadtgliederung:     | 6 Stadtteile                                                 |
| Adresse der          |                                                              |
| Stadtverwaltung:     | Rathaus                                                      |
| Marktplatz 2         |                                                              |
| 64832 Babenhausen    |                                                              |
| Website:             | www.babenhausen.de                                           |
| Bürgermeister:       | Dominik Stadler (parteilos)                                  |
+----------------------+--------------------------------------------------------------+

https://de.wikipedia.org/wiki/Bacharachhttps://de.wikipedia.org/wiki/Backnang

update3: если я запустил этот код, чтобы получить 300 записей. это работает хорошо - если я запущу это, чтобы получить 2400, это не удастся..

import requests
from bs4 import BeautifulSoup
import pandas as pd


def get_info(city_url: str) -> dict:
    info_data = {}
    response = requests.get(city_url)
    soup = BeautifulSoup(response.text, 'lxml')
    for x in soup.find('tbody').find_all(
            lambda tag: tag.name == 'tr' and tag.get('class') == ['hintergrundfarbe-basis']):
        if not x.get('style'):
            if 'Koordinaten' in x.get_text():
                info_data['Koordinaten'] = x.findNext('span', class_='coordinates').get_text()
            else:
                info_data[x.get_text(strip=True).split(':')[0]] = x.get_text(strip=True).split(':')[-1]
                info_data['Web site'] = soup.find('a', {'title':'Website'}).findNext('a').get('href')
    return info_data


cities = []
response = requests.get('https://de.wikipedia.org/wiki/Liste_der_St%C3%A4dte_in_Deutschland#Liste_der_St%C3%A4dte_in_Deutschland')
soup = BeautifulSoup(response.text, 'lxml')
for city in soup.find_all('dd')#[:2500]:
    city_url = 'https://de.wikipedia.org' + city.findNext('a').get('href')
    result = {'City': city.get_text(), 'URL': 'https://de.wikipedia.org' + city.findNext('a').get('href')}
    result |= get_info(city_url)
    cities.append(result)
df = pd.DataFrame(cities)
print(df.to_string())


------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-28-4391c852fd75> in <cell line: 24>()
     25     city_url = 'https://de.wikipedia.org' + city.findNext('a').get('href')
     26     result = {'City': city.get_text(), 'URL': 'https://de.wikipedia.org' + city.findNext('a').get('href')}
---> 27     result |= get_info(city_url)
     28     cities.append(result)
     29 df = pd.DataFrame(cities)

<ipython-input-28-4391c852fd75> in get_info(city_url)
     15             else:
     16                 info_data[x.get_text(strip=True).split(':')[0]] = x.get_text(strip=True).split(':')[-1]
---> 17                 info_data['Web site'] = soup.find('a', {'title':'Website'}).findNext('a').get('href')
     18     return info_data
     19 

AttributeError: 'NoneType' object has no attribute 'findNext'
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Каждый город в теге dd, поэтому вы можете просто использовать функцию find_all(), чтобы получить имя и URL. Затем пройдите по каждому URL-адресу и получите таблицу. В примере всего 5 повторений, удаляем [:5] в цикле на полную

import requests
from bs4 import BeautifulSoup
import pandas as pd


def get_info(city_url: str) -> dict:
    info_data = {}
    response = requests.get(city_url)
    soup = BeautifulSoup(response.text, 'lxml')
    for x in soup.find('tbody').find_all(
            lambda tag: tag.name == 'tr' and tag.get('class') == ['hintergrundfarbe-basis']):
        if not x.get('style'):
            if 'Koordinaten' in x.get_text():
                info_data['Koordinaten'] = x.findNext('span', class_='coordinates').get_text()
            else:
                info_data[x.get_text(strip=True).split(':')[0]] = x.get_text(strip=True).split(':')[-1]
    if soup.find('a', {'title': 'Website'}):
        info_data['Web site'] = soup.find('a', {'title': 'Website'}).findNext('a').get('href')
    return info_data


cities = []
response = requests.get('https://de.wikipedia.org/wiki/Liste_der_St%C3%A4dte_in_Deutschland#Liste_der_St%C3%A4dte_in_Deutschland')
soup = BeautifulSoup(response.text, 'lxml')
for city in soup.find_all('dd'):
    city_url = 'https://de.wikipedia.org' + city.findNext('a').get('href')
    result = {'City': city.get_text(), 'URL': 'https://de.wikipedia.org' + city.findNext('a').get('href')}
    result |= get_info(city_url)
    cities.append(result)
df = pd.DataFrame(cities)
print(df.to_string())

ВЫХОД:

             City                                         URL           Koordinaten           Bundesland Regierungsbezirk            Landkreis         Höhe      Fläche                  Einwohner     Bevölkerungsdichte Postleitzahl Vorwahl       Kfz-Kennzeichen Gemeindeschlüssel   Adresse derStadtverwaltung   Bürgermeister      Postleitzahlen                  Vorwahlen             Stadtgliederung        Oberbürgermeisterin        Oberbürgermeister      Erste Bürgermeisterin Erster Bürgermeister
0       Aach (BW)  https://de.wikipedia.org/wiki/Aach_(Hegau)   47° 51′ N, 8° 51′ O    Baden-Württemberg         Freiburg             Konstanz  545 m ü.NHN   10,68 km2     2384(31. Dez. 2022)[1]   223 Einwohner je km2        78267   07774                KN,STO       08 3 35 001     Hauptstraße 1678267 Aach  Manfred Ossola                 NaN                        NaN                         NaN                        NaN                      NaN                        NaN                  NaN
1     Aachen (NW)        https://de.wikipedia.org/wiki/Aachen    50° 47′ N, 6° 5′ O  Nordrhein-Westfalen             Köln  Städteregion Aachen  175 m ü.NHN  160,85 km2  252.769(31. Dez. 2023)[1]  1571 Einwohner je km2          NaN     NaN               AC, MON       05 3 34 002            Markt52062 Aachen             NaN         52062–52080  0241, 02405, 02407, 02408               7Stadtbezirke  Sibylle Keupen(parteilos)                      NaN                        NaN                  NaN
2      Aalen (BW)         https://de.wikipedia.org/wiki/Aalen   48° 50′ N, 10° 6′ O    Baden-Württemberg        Stuttgart          Ostalbkreis  430 m ü.NHN  146,58 km2   68.816(31. Dez. 2022)[1]   469 Einwohner je km2          NaN     NaN                AA, GD       08 1 36 088                          NaN             NaN  73430–73434, 73453        07361, 07366, 07367  Kernstadtund 8Stadtbezirke                        NaN  Frederick Brütting(SPD)                        NaN                  NaN
3   Abenberg (BY)      https://de.wikipedia.org/wiki/Abenberg  49° 15′ N, 10° 58′ O               Bayern    Mittelfranken                 Roth  414 m ü.NHN   48,41 km2     5614(31. Dez. 2023)[1]   116 Einwohner je km2        91183   09178               RH, HIP       09 5 76 111  Stillaplatz 191183 Abenberg             NaN                 NaN                        NaN             14Gemeindeteile                        NaN                      NaN  Susanne König (parteilos)                  NaN
4  Abensberg (BY)     https://de.wikipedia.org/wiki/Abensberg  48° 49′ N, 11° 51′ O               Bayern     Niederbayern              Kelheim  370 m ü.NHN   60,26 km2   14.685(31. Dez. 2023)[1]   244 Einwohner je km2        93326   09443  KEH,MAI,PAR, RID,ROL       09 2 73 111  Stadtplatz 193326 Abensberg             NaN                 NaN                        NaN             22Gemeindeteile                        NaN                      NaN                        NaN    Bernhard Resch[2]

большое спасибо дорогой Сергей - это больше, чем ожидалось. Потрясающе. - Огромное спасибо! Кстати, как получить полные результаты, которые хранятся в файле df. - и содержащий все данные - в поле info.. (см. изображение выше) - с контактной информацией и т. д.

zero 28.07.2024 20:00

@zero, ты имеешь в виду веб-сайт?

Sergey K 28.07.2024 20:12

@zero Таблица содержит ненужные метаданные и карты, которые нет смысла добавлять в выходную таблицу. Если вы хотите добавить веб-сайт, прежде чем возвращать переменную info_data, напишите - info_data['Web site'] = soup.find('a', {'title': 'Website'}).findNext('a').get('href') на том же уровне пространства, что и return

Sergey K 28.07.2024 20:21

или просто удали if not x.get('style'): и всё получишь

Sergey K 28.07.2024 20:22

привет дорогой Сергей! Я добавил дополнительную информацию в стартовый пост. кстати, спасибо за дополнительную информацию--

zero 28.07.2024 20:30

Конечно, карта нам не нужна. Контактные данные - это самое интересное здесь.

zero 28.07.2024 20:33

большое спасибо... кстати: update3: если я запущу этот код, чтобы получить 300 записей. это работает хорошо - если я запущу это, чтобы получить 2400, это не удастся.. - почему это так !?

zero 28.07.2024 23:32

@zero, наверное, у тебя ошибка 429 http? просто добавьте time.sleep(5) в цикл find_all, или вы получите еще одну ошибку?

Sergey K 29.07.2024 00:05

Дорогой Сергей! Большое спасибо за ответ. Я запускаю это в google-colab - и с небольшим количеством результатов (всего 300 записей) все идет хорошо - но если я установлю * Soup.find_all('dd')#[:2500]:`это большое значение - тогда Я столкнулся с ошибками, описанными в последнем обновлении, которое я добавил в исходный пост — см. выше.

zero 29.07.2024 10:06

см. выше — результат, который я получаю… он содержит следующее утверждение: «AttributeError: Объект «NoneType» не имеет атрибута «findNext» и да — я запускаю его в Google Colab… хотелось бы услышать ваше мнение. ...

zero 29.07.2024 10:07

@zero у некоторых ссылок нет веб-сайта, я обновляю ответ и получаю полный результат

Sergey K 29.07.2024 10:30

потрясающе - это намного больше, чем ожидалось - большой привет вам!! вы мне очень помогли!!

zero 29.07.2024 12:01

Другие вопросы по теме

Как фильтровать фрейм данных pandas для строк, содержащих все подстроки в заданном списке
Почему PyCharm запрашивает старую версию Pandas и как ее остановить?
Почему предупреждение: «FutureWarning: установка элемента несовместимого типа d устарела и вызовет ошибку в будущей версии pandas»?
В кадре данных замените значения из одного столбца с несколькими условиями, а не в одной строке, в другой столбец
Каков наиболее эффективный способ многопроцессорной обработки очень большого кадра данных?
Сортировать фрейм данных Pandas по промежуточной сумме и подсчитывать
Как я могу отфильтровать df «A», используя в качестве условия сравнение с df «B»?
Преобразовать время в секунды [удалив миллисекунды]
Группировка фреймов данных Pandas с применением функции с переменным количеством аргументов
Как найти количество строк в группе, поскольку для кадра данных pandas возникло ненулевое значение?