Цикл по нескольким веб-страницам, очищающий одну и ту же информацию: Python и Beautiful Soup

#python #html #beautifulsoup

#python #HTML #beautifulsoup

Вопрос:

Я использую Python и Beautiful Soup для очистки веб-страницы, содержащей множество поселений в Африке и Азии, у каждого из которых есть своя веб-страница. Это веб-сайт:http://knowyourcity.info/explore-our-data /

У меня есть этот код для получения атрибутов с отдельной страницы:

 from requests import get
url = 'http://knowyourcity.info/settlement/1846/5119249'
response = get(url)

from bs4 import BeautifulSoup
html_soup = BeautifulSoup(response.text, "html.parser")
type(html_soup)

headers_containers = html_soup.find('div', class_ = 'settlement-base-status section text-center')
name = headers_containers.h2.text
year_established = headers_containers.h3.text

headers1_containers = html_soup.find('div', class_ = 'col-xs-12 text-center')
country = headers1_containers.h4.a.text

headers2_containers = html_soup.find('div', class_ = 'bold-it', id = "population")
population = headers2_containers.text
  

Но я хочу иметь возможность перебирать каждое урегулирование и помещать атрибуты в таблицу, где изменяется число в конце URL. Однако номера поселений не меняются постепенно и кажутся мне довольно случайными. Кто-нибудь знает функцию цикла, которую я мог бы использовать для этого? Спасибо

Ответ №1:

Данные о населенных пунктах загружаются с внешнего URL. Вы можете использовать этот скрипт для создания URL-адресов:

 import json
import requests
from bs4 import BeautifulSoup


url = 'http://knowyourcity.info/wp-content/themes/sdinet/ajax/get-filter.php'

# sometimes the server returns error, so repeat 'till success:
while True:
    try:
        data = requests.post(url).json()
        break
    except:
        pass

# uncomment this to print all data:
# print(json.dumps(data, indent=4))

u = 'http://knowyourcity.info/settlement/{}/{}'

for k, v in data['verified'].items():
    for kk, vv in v.items():
        if isinstance(vv, list):
            for vvv in vv:
                print('{:<20} {:<30} {:<50} {}'.format(k, kk, vvv['name'], u.format(vvv['form_id'], vvv['ona_id'])))
        else:
            for kkk, vvv in vv.items():
                print('{:<20} {:<30} {:<50} {}'.format(k, kk, vvv.get('name', '-'), u.format(vvv['form_id'], vvv['ona_id'])))
  

С принтами:

 38_benin             38001_cotonou        AGONKAME - TOTO                http://knowyourcity.info/settlement/344923/51863092
38_benin             38001_cotonou        Ahouansori Ague                http://knowyourcity.info/settlement/344923/43698638
38_benin             38001_cotonou        DJIDJE 1 AYINADJE              http://knowyourcity.info/settlement/344923/51327770
38_benin             38001_cotonou        hinde nord                     http://knowyourcity.info/settlement/344923/51869427
38_benin             38001_cotonou        KPANKPAN LA LIBERTE            http://knowyourcity.info/settlement/344923/51276811
38_benin             38001_cotonou        KPAYOCODJI                     http://knowyourcity.info/settlement/344923/51986803
38_benin             38001_cotonou        MIGBEHOUE                      http://knowyourcity.info/settlement/344923/51990855
38_benin             38001_cotonou        MINONTCHOU-TOTO                http://knowyourcity.info/settlement/344923/53173309
Ghana                Accra                ABELENKPE                      http://knowyourcity.info/settlement/1846/5119249
Ghana                Accra                ABOFO                          http://knowyourcity.info/settlement/1846/5193260
Ghana                Accra                ABOSSEY OKAI                   http://knowyourcity.info/settlement/1846/9015532
Ghana                Accra                ACHIMOTA                       http://knowyourcity.info/settlement/1846/5185027
Ghana                Accra                ADABRAKA                       http://knowyourcity.info/settlement/1846/15080768

...and so on.
  

РЕДАКТИРОВАТЬ: Чтобы сохранить URL-адреса в виде списка, вы можете использовать:

 import json
import requests
from bs4 import BeautifulSoup


url = 'http://knowyourcity.info/wp-content/themes/sdinet/ajax/get-filter.php'

# sometimes the server returns error, so repeat 'till success:
while True:
    try:
        data = requests.post(url).json()
        break
    except:
        pass

# uncomment this to print all data:
# print(json.dumps(data, indent=4))

u = 'http://knowyourcity.info/settlement/{}/{}'

urllist = []
for k, v in data['verified'].items():
    for kk, vv in v.items():
        if isinstance(vv, list):
            for vvv in vv:
                urllist.append(u.format(vvv['form_id'], vvv['ona_id']))
                print('{:<20} {:<30} {:<50} {}'.format(k, kk, vvv['name'], u.format(vvv['form_id'], vvv['ona_id'])))
        else:
            for kkk, vvv in vv.items():
                urllist.append(u.format(vvv['form_id'], vvv['ona_id']))
                print('{:<20} {:<30} {:<50} {}'.format(k, kk, vvv.get('name', '-'), u.format(vvv['form_id'], vvv['ona_id'])))

# all urls are inside urllist, print them on screen:
for u in urllist:
    print(u)
  

С принтами:

 ...

http://knowyourcity.info/settlement/1853/55602115
http://knowyourcity.info/settlement/1853/10800809
http://knowyourcity.info/settlement/1853/10801751
http://knowyourcity.info/settlement/1853/10801676
http://knowyourcity.info/settlement/1853/10800885
http://knowyourcity.info/settlement/1853/10802010
http://knowyourcity.info/settlement/1853/10800886
http://knowyourcity.info/settlement/1853/10800915
http://knowyourcity.info/settlement/1853/10801006
http://knowyourcity.info/settlement/1853/10801083
  

Комментарии:

1. Большое вам спасибо за это — действительно полезно. Для последнего раздела, однако, я возвращаю ошибку: Трассировка (последний последний вызов): Файл «<ipython-input-386-91aee68020d8>», строка 3, в <module> if isinstance (vv, list): TypeError: isinstance () аргумент 2 должен быть типом или кортежем типов

2. @Georgia вы, вероятно, использовали ранее переменную с именем list и скрытый встроенный тип python list . Переименуйте свою переменную во что-нибудь другое.

3. Ах, здорово, да, это сработало, извините, еще один вопрос, поскольку я совсем новичок в этом! Как бы я затем просматривал каждый из этих URL-адресов и извлекал информацию, предоставляет ли вышеуказанные URL-адреса в виде списка? Спасибо!

4. @Georgia Смотрите мою правку. Все URL-адреса находятся внутри urllist