Извлечение данных из результата URL с помощью специального форматирования - PullRequest
4 голосов
/ 30 октября 2010

У меня есть URL:
http://somewhere.com/relatedqueries?limit=2&query=seedterm

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

URL-адрес предоставляет текстовый результат, отформатированный таким образом:
oo.visualization.Query.setResponse ({версия: '0.5', reqId: '0', статус: 'оК', сиг: '1303596067112929220', таблица {смещ_по_столбцам: [{ID: 'оценка', метка: 'Score', введите: 'число', шаблон: '#, ## 0. ### '}, {ID:' запрос», метка: 'запрос', тип: 'строка', шаблон: ''}], строки: [{с: [{v: 0,9894380670262618, F: '0.99'}, {v: 'newterm1'}]}, {с: [{v: 0,9894380670262618, F: '0.99'}, {v: 'newterm2'}]}], р: { 'totalResultsCount': '7727'}}});

Я хотел бы написать скрипт на python, который принимает два аргумента (число предела и начальный размер запроса), перейти к извлечению данных в режиме онлайн, проанализировать результат и вернуть список с новыми условиями ['newterm1', 'newterm2'] в данном случае.

Я бы хотел получить некоторую помощь, особенно с извлечением URL, так как я никогда не делал этого раньше.

Ответы [ 2 ]

12 голосов
/ 30 октября 2010

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

Подзадачи

Существует несколько проблем, которые необходимо решить перед составлением завершенного сценария:

  1. Формирование URL запроса: Создание настроенного URL запроса из шаблона
  2. Извлечение данных: Фактическое выполнение запроса
  3. Распаковка JSONP : Возвращенные данные выглядят как JSON , завернутые в вызов функции JavaScript
  4. Обход графа объекта: Навигация по результату для поиска нужных битов информации

Формирование URL запроса

Это просто простое форматирование строки.

url_template = 'http://somewhere.com/relatedqueries?limit={limit}&query={seedterm}'
url = url_template.format(limit=2, seedterm='seedterm')

Python2 Примечание

Здесь вам понадобится оператор форматирования строки (%).

url_template = 'http://somewhere.com/relatedqueries?limit=%(limit)d&query=%(seedterm)s'
url = url_template % dict(limit=2, seedterm='seedterm')

Получение данных

Вы можете использовать встроенныйв модуле urllib.request для этого.

import urllib.request
data = urllib.request.urlopen(url) # url from previous section

Это возвращениеэто файлоподобный объект с именем data.Вы также можете использовать оператор with здесь:

with urllib.request.urlopen(url) as data:
    # do processing here

Python 2 Note

Импорт urllib2 вместо urllib.request.

Распаковка JSONP

Вставленный вами результат выглядит как JSONP.Учитывая, что вызываемая функция переноса (oo.visualization.Query.setResponse) не изменяется, мы можем просто удалить этот вызов метода.

result = data.read()

prefix = 'oo.visualization.Query.setResponse('
suffix = ');'

if result.startswith(prefix) and result.endswith(suffix):
    result = result[len(prefix):-len(suffix)]

Синтаксический анализ JSON

Результирующая строка resultэто просто данные JSON.Проанализируйте его с помощью встроенного модуля json.

import json

result_object = json.loads(result)

Обход графа объектов

Теперь у вас есть result_object, который представляет ответ JSON.Сам объект будет dict с такими клавишами, как version, reqId и так далее.Исходя из вашего вопроса, вот что вам нужно сделать, чтобы создать свой список.

# Get the rows in the table, then get the second column's value for
# each row
terms = [row['c'][2]['v'] for row in result_object['table']['rows']]

Соберите все вместе

#!/usr/bin/env python3

"""A script for retrieving and parsing results from requests to
somewhere.com.

This script works as either a standalone script or as a library. To use
it as a standalone script, run it as `python3 scriptname.py`. To use it
as a library, use the `retrieve_terms` function."""

import urllib.request
import json
import sys

E_OPERATION_ERROR = 1
E_INVALID_PARAMS = 2

def parse_result(result):
    """Parse a JSONP result string and return a list of terms"""
    prefix = 'oo.visualization.Query.setResponse('
    suffix = ');'

    # Strip JSONP function wrapper
    if result.startswith(prefix) and result.endswith(suffix):
        result = result[len(prefix):-len(suffix)]

    # Deserialize JSON to Python objects
    result_object = json.loads(result)

    # Get the rows in the table, then get the second column's value
    # for each row
    return [row['c'][2]['v'] for row in result_object['table']['rows']]

def retrieve_terms(limit, seedterm):
    """Retrieves and parses data and returns a list of terms"""
    url_template = 'http://somewhere.com/relatedqueries?limit={limit}&query={seedterm}'
    url = url_template.format(limit=limit, seedterm=seedterm)

    try:
        with urllib.request.urlopen(url) as data:
            data = perform_request(limit, seedterm)
            result = data.read()
    except:
        print('Could not request data from server', file=sys.stderr)
        exit(E_OPERATION_ERROR)

    terms = parse_result(result)
    print(terms)

def main(limit, seedterm):
    """Retrieves and parses data and prints each term to standard output"""
    terms = retrieve_terms(limit, seedterm)
    for term in terms:
        print(term)

if __name__ == '__main__'
    try:
        limit = int(sys.argv[1])
        seedterm = sys.argv[2]
    except:
        error_message = '''{} limit seedterm

limit must be an integer'''.format(sys.argv[0])
        print(error_message, file=sys.stderr)
        exit(2)

    exit(main(limit, seedterm))

Python 2.7 версия

#!/usr/bin/env python2.7

"""A script for retrieving and parsing results from requests to
somewhere.com.

This script works as either a standalone script or as a library. To use
it as a standalone script, run it as `python2.7 scriptname.py`. To use it
as a library, use the `retrieve_terms` function."""

import urllib2
import json
import sys

E_OPERATION_ERROR = 1
E_INVALID_PARAMS = 2

def parse_result(result):
    """Parse a JSONP result string and return a list of terms"""
    prefix = 'oo.visualization.Query.setResponse('
    suffix = ');'

    # Strip JSONP function wrapper
    if result.startswith(prefix) and result.endswith(suffix):
        result = result[len(prefix):-len(suffix)]

    # Deserialize JSON to Python objects
    result_object = json.loads(result)

    # Get the rows in the table, then get the second column's value
    # for each row
    return [row['c'][2]['v'] for row in result_object['table']['rows']]

def retrieve_terms(limit, seedterm):
    """Retrieves and parses data and returns a list of terms"""
    url_template = 'http://somewhere.com/relatedqueries?limit=%(limit)d&query=%(seedterm)s'
    url = url_template % dict(limit=2, seedterm='seedterm')

    try:
        with urllib2.urlopen(url) as data:
            data = perform_request(limit, seedterm)
            result = data.read()
    except:
        sys.stderr.write('%s\n' % 'Could not request data from server')
        exit(E_OPERATION_ERROR)

    terms = parse_result(result)
    print terms

def main(limit, seedterm):
    """Retrieves and parses data and prints each term to standard output"""
    terms = retrieve_terms(limit, seedterm)
    for term in terms:
        print term

if __name__ == '__main__'
    try:
        limit = int(sys.argv[1])
        seedterm = sys.argv[2]
    except:
        error_message = '''{} limit seedterm

limit must be an integer'''.format(sys.argv[0])
        sys.stderr.write('%s\n' % error_message)
        exit(2)

    exit(main(limit, seedterm))
1 голос
/ 30 октября 2010

я не очень хорошо понял вашу проблему, потому что из вашего кода мне кажется, что вы используете API визуализации (кстати, впервые слышу об этом).

Но хорошо, если вы просто ищете способ получения данных с веб-страницы, вы можете использовать urllib2 , это просто для получения данных, и если вы хотите проанализировать извлеченные данные, вам придется используйте более подходящую библиотеку, такую ​​как BeautifulSoop

если вы имеете дело с другим веб-сервисом (RSS, Atom, RPC), а не с веб-страницами, вы можете найти набор библиотек Python, которые вы можете использовать и которые прекрасно работают с каждым сервисом.

import urllib2

from BeautifulSoup import BeautifulSoup

result =  urllib2.urlopen('http://somewhere.com/relatedqueries?limit=%s&query=%s' % (2, 'seedterm'))

htmletxt = resul.read()

result.close()

soup = BeautifulSoup(htmltext, convertEntities="html" )

# you can parse your data now check BeautifulSoup API.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...