#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
и скрытый встроенный тип pythonlist
. Переименуйте свою переменную во что-нибудь другое.3. Ах, здорово, да, это сработало, извините, еще один вопрос, поскольку я совсем новичок в этом! Как бы я затем просматривал каждый из этих URL-адресов и извлекал информацию, предоставляет ли вышеуказанные URL-адреса в виде списка? Спасибо!
4. @Georgia Смотрите мою правку. Все URL-адреса находятся внутри
urllist