Простейший скрапер

Предположим, нужны сведения о странах: их международные коды (ISO-3166), названия, население, площадь и континент. Такой список есть на сайте GeoNames 1.

Исходный код страницы

Открыв исходный код страницы http://www.geonames.org/countries/ 2, мы увидим, что нужные данные располагаются в таблице:

<table class="restable sortable" id="countries">
<tr>
    <th>ISO-3166<br>alpha2</th><th>ISO-3166<br>alpha3</th>
    <th>ISO-3166<br>numeric</th><th>fips</th>
    <th>Country</th><th>Capital</th>
    <th>Area in km&sup2;</th>
    <th>Population</th>
    <th>Continent</th>
</tr>
<tr>
    <td><a name="AD"></a>AD</td>
    <td>AND</td>
    <td>020</td>
    <td>AN</td>
    <td><a href="/countries/AD/andorra.html">Andorra</a></td>
    <td>Andorra la Vella</td>
    <td class="rightalign">468.0</td>
    <td class="rightalign">84,000</td>
    <td>EU</td>
</tr>
...
</table>

У таблицы есть уникальный идентификатор: "countries":

<table class="restable sortable" id="countries">

Он поможет парсеру легко ее отыскать.

Программа

Простейший скрапер мог бы выглядеть так.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import requests
from bs4 import BeautifulSoup

COLUMNS = (0, 4, 5, 6, 7)

def iter_countries(table):
    for i, tr in enumerate(table.find_all('tr')):
        if i == 0:
            continue # skip header
        yield [ td.text for j, td in enumerate(tr.find_all('td')) if j in COLUMNS ]


resp = requests.get('http://www.geonames.org/countries/')
soup = BeautifulSoup(resp.text)
table = soup.find('table', id='countries')
for country in iter_countries(table):
    print country
  • Строка 4: вслед за импортом нужных библиотек объявляется кортеж COLUMNS, содержащий индексы столбцов таблицы, которые нас интересуют: код, название, столица, площадь, население.

  • Строки 6 - 10: функция-итератор, которая при каждом вызове возвращает данные по очередной стране. На входе она получает объект BeautifulSoup, представляющий таблицу. В таблице она перебирает все строки (теги <tr>), а из каждой строки выбирает столбцы (<td>), по индексам из списка COLUMNS.

  • Строка 13: простейший GET-запрос. Результатом является экземпляр класса requests.Response.

  • Строка 14: создается объект BeautifulSoup, получающий в конструкторе resp.text — контент страницы.
  • Строка 15: находим таблицу со странами по уникальному идентификатору id="countries"
  • Строки 16 - 17: вызываем функцию-итератор iter_countries, получаем страну за страной и выводим результаты построчно в консоль.

Результат

[u'AD', u'Andorra', u'Andorra la Vella', u'468.0', u'84,000']
[u'AE', u'United Arab Emirates', u'Abu Dhabi', u'82,880.0', u'4,975,593']
[u'AF', u'Afghanistan', u'Kabul', u'647,500.0', u'29,121,286']
[u'AG', u'Antigua and Barbuda', u"St. John's", u'443.0', u'86,754']
...

Полученные данные можно сохранить в том или ином виде и использовать для работы.

Заключение

...Итак, необходимо в первую очередь изучить исходный код страницы. Так мы узнаем, какие теги/аттрибуты позволят программе извлечь нужные данные. После этого пишем программу, которая:

  1. Получив адрес, запрашивает страницу — точно так же, как любой браузер. В нашем случае за это отвечает питоновская библиотека Requests.
  2. Находит в HTML-коде нужные данные. Этим занимается библиотека BeautifulSoup.

Такова общая схема работы любого скрапера.


  1. Если читателю на самом деле нужна информация о странах, скрапер писать необязательно. Geonames бесплатно предоставляет широкий спектр географических данных через API, а также в виде файлов. 

  2. В Firefox для того, чтобы увидеть исходный текст, надо вызывать контекстное меню, щелкнув правой кнопкой мыши в любом месте страницы и выбрать пункт Исходный код страницы

social

Яндекс.Метрика