Как я могу получить данные из инструмента веб-запросов Израильского бюро статистики? - PullRequest
4 голосов
/ 21 июня 2011

следующий URL:

http://www.cbs.gov.il/ts/ID40d250e0710c2f/databank/series_func_e_v1.html?level_1=31&level_2=1&level_3=7

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

Спасибо.

Ответы [ 3 ]

8 голосов
/ 21 июня 2011

Взгляните на WWW :: Mechanize и WWW :: HtmlUnit .

#!/usr/bin/perl

use strict;
use warnings;

use WWW::Mechanize;

my $m = WWW::Mechanize->new;

#get page
$m->get("http://www.cbs.gov.il/ts/ID40d250e0710c2f/databank/series_func_e_v1.html?level_1=31&level_2=1&level_3=7");

#submit the form on the first page
$m->submit_form(
    with_fields => {
        name_tatser => 2, #Orders for export
    }
);

#now that we have the second page, submit the form on it
$m->submit_form(
    with_fields => {
        name_ser => 1576, #Number of companies that answered
    }
);

#and so on...

#printing the source HTML is a good way
#to find out what you need to do next
print $m->content;
3 голосов
/ 22 июня 2011

Для отправки форм вы можете использовать Механизированный модуль Python :

import mechanize
import pprint
import lxml.etree as ET
import lxml.html as lh
import urllib
import urllib2

browser=mechanize.Browser()
browser.open("http://www.cbs.gov.il/ts/ID40d250e0710c2f/databank/series_func_e_v1.html?level_1=31&level_2=1&level_3=7")
browser.select_form(nr=0)

Здесь мы посмотрим на доступные варианты:

pprint.pprint(browser.form.controls[-2].items)
# [<Item name='1' id=None selected='selected' contents='Volume of orders for the domestic market' value='1' label='Volume of orders for the domestic market'>,
#  <Item name='2' id=None contents='Orders for export' value='2' label='Orders for export'>,
#  <Item name='3' id=None contents='The volume of production' value='3' label='The volume of production'>,
#  <Item name='4' id=None contents='The volume of sales' value='4' label='The volume of sales'>,
#  <Item name='5' id=None contents='Stocks of finished goods' value='5' label='Stocks of finished goods'>,
#  <Item name='6' id=None contents='Access to credit for the company' value='6' label='Access to credit for the company'>,
#  <Item name='7' id=None contents='Change in the number of employees' value='7' label='Change in the number of employees'>]

choices=[item.attrs['value'] for item in browser.form.controls[-2].items]
print(choices)
# ['1', '2', '3', '4', '5', '6', '7']

browser.form['name_tatser']=['2']
browser.submit()

Мы можем повторить это для каждой из следующих форм:

browser.select_form(nr=1)

choices=[item.attrs['value'] for item in browser.form.controls[-2].items]
print(choices)
# ['1576', '1581', '1594', '1595', '1596', '1598', '1597', '1593']

browser.form['name_ser']=['1576']
browser.submit()

browser.select_form(nr=2)

choices=[item.attrs['value'] for item in browser.form.controls[-2].items]
print(choices)
# ['32', '33', '34', '35', '36', '37', '38', '39', '40', '41']

browser.form['data_kind']=['33']
browser.submit()

browser.select_form(nr=3)
browser.form['ybegin']=['2010']
browser.form['mbegin']=['1']
browser.form['yend']=['2011']
browser.form['mend']=['5']
browser.submit()

На данный момент у вас есть три варианта:

  1. Анализ данных из источника HTML
  2. Скачать файл .xls
  3. Скачать файл XML

У меня нет опыта разбора .xls в Python, поэтому я пропустил эту опцию.

Синтаксический анализ HTML возможен с помощью BeautifulSoup или lxml. возможно это было бы самым коротким решением, но мне не сразу было понятно, какой правильный XPath для HTML, поэтому я остановился на XML:

Чтобы загрузить XML с веб-сайта cbs.gov.il, достаточно нажать кнопку, которая вызывает функцию javascript. Э-э-э - механизация не может выполнять функции JavaScript. К счастью, JavaScript просто собирает новый URL. Вытащить параметры с помощью lxml легко:

content=browser.response().read()
doc=lh.fromstring(content)
params=dict((elt.attrib['name'],elt.attrib['value']) for elt in doc.xpath('//input'))
params['king_format']=2
url='http://www.cbs.gov.il/ts/databank/data_ts_format_e.xml'
params=urllib.urlencode(dict((p,params[p]) for p in [
    'king_format',
    'tod',
    'time_unit_list',
    'mend',
    'yend',
    'co_code_list',
    'name_tatser_list',
    'ybegin',
    'mbegin',
    'code_list',
    'co_name_tatser_list',
    'level_1',
    'level_2',
    'level_3']))

browser.open(url+'?'+params)
content=browser.response().read()

Теперь мы подошли к другому камню преткновения: XML кодируется в iso-8859-8-i. Python не распознает эту кодировку. Не зная, что делать, я просто заменил iso-8859-8-i на iso-8859-8. Я не знаю, какие плохие побочные эффекты это может вызвать.

# A hack, since I do not know how to deal with iso-8859-8-i
content=content.replace('iso-8859-8-i','iso-8859-8')
doc=ET.fromstring(content)

Как только вы доберетесь до этого, разбирать XML очень просто:

for series in doc.xpath('/series_ts/Data_Set/Series'):
    print(series.attrib)
    # {'calc_kind': 'Weighted',
    #  'name_ser': 'Number Of Companies That Answered',
    #  'get_time': '2011-06-21',
    #  'name_topic': "Business Tendency Survey - Distributions Of Businesses By Industry, Kind Of Questions And Answers  - Manufacturing - Company'S Experience Over The Past Three Months - Orders For Export",
    #  'time_unit': 'Month',
    #  'code_series': '22978',
    #  'data_kind': '5-10 Employed Persons',
    #  'decimals': '0',
    #  'unit_kind': 'Number'}

    for elt in series.xpath('obs'):
        print(elt.attrib)
        # {'time_period': ' 2010-12', 'value': '40'}
        # {'time_period': ' 2011-01', 'value': '38'}
        # {'time_period': ' 2011-02', 'value': '40'}
        # {'time_period': ' 2011-03', 'value': '36'}
        # {'time_period': ' 2011-04', 'value': '30'}
        # {'time_period': ' 2011-05', 'value': '33'}
1 голос
/ 21 июня 2011

Вам также следует взглянуть на Scrapy , которая является платформой для веб-сканера Python. См. «Scrapy с первого взгляда» для введения: http://doc.scrapy.org/intro/overview.html

...