Извлечение частей веб-страницы с помощью python

Итак, у меня есть проект поиска/ввода данных, и я хочу извлечь определенную часть веб-страницы и сохранить ее в текстовом файле. У меня есть текстовый файл URL-адресов, и программа должна извлекать одну и ту же часть страницы для каждого URL-адреса.

В частности, программа копирует юридический акт, следующий за «Юридическим органом:» на таких страницах, как это. Как видите, указан только один закон. Однако некоторые URL также выглядят как это, это означает, что существует несколько отдельных уставов.

Мой код работает для страниц первого вида:

from sys import argv
from urllib2 import urlopen

script, urlfile, legalfile = argv
input = open(urlfile, "r")
output = open(legalfile, "w")

def get_legal(page):
    # this is where Legal Authority: starts in the code
    start_link = page.find('Legal Authority:')
    start_legal = page.find('">', start_link+1)
    end_link = page.find('<', start_legal+1)
    legal = page[start_legal+2: end_link]
    return legal

for line in input:
  pg = urlopen(line).read()
  statute = get_legal(pg)
  output.write(get_legal(pg))

Предоставление мне желаемого имени закона в выходном файле «legalfile» .txt. Однако он не может копировать несколько имен уставов. Я пробовал что-то вроде этого:

def get_legal(page):
# this is where Legal Authority: starts in the code
    end_link = ""
    legal = ""
    start_link = page.find('Legal Authority:')
    while (end_link != '</a>&nbsp;'):
        start_legal = page.find('">', start_link+1)

        end_link = page.find('<', start_legal+1)
        end2 = page.find('</a>&nbsp;', end_link+1)
        legal += page[start_legal+2: end_link] 
        if 
        break
    return legal

Поскольку каждый список статутов заканчивается на '</a>&nbsp;' (проверьте источник любой из двух ссылок), я подумал, что могу использовать этот факт (имея его в конце индекса), чтобы пройти и собрать все статуты в одну строку. Любые идеи?


person Emir    schedule 14.07.2012    source источник
comment
Страница, которую вы очищаете, предлагает эти удобные ссылки для загрузки данных RIN в XML. Чем бы ни был RIN, есть чистый XML. Разве вы не можете использовать это вместо этого? (<LEGAL_AUTHORITY_LIST><LEGAL_AUTHORITY>blah1</LEGAL_AUTHORITY><LEGAL_AUTHORITY>blah2</LEGAL_AUTHORITY></LEGAL_AUTHORITY_LIST>)   -  person tiwo    schedule 14.07.2012
comment
С библиотекой python ElementTree и предложением @tiwo разбор XMl должен быть предельно простым   -  person ctrlc-root    schedule 14.07.2012
comment
Только что заметил ссылку XML - спасибо. Но похоже, что мне нужно загрузить каждый XML-файл, и мне нужно просмотреть сотни уникальных RIN. Есть ли код Python для эффективной загрузки XML?   -  person Emir    schedule 14.07.2012


Ответы (2)


Я бы предложил использовать BeautifulSoup для разбора и поиска вашего html. Это будет намного проще, чем обычный поиск строк.

Вот пример, который извлекает все теги <a>, найденные в теге <td>, который содержит тег <b>Legal Authority:</b>. (Обратите внимание, что я использую библиотеку requests для получения содержимого страницы здесь - это просто рекомендуемая и очень простая в использовании альтернатива urlopen.)

import requests
from BeautifulSoup import BeautifulSoup

# fetch the content of the page with requests library
url = "http://www.reginfo.gov/public/do/eAgendaViewRule?pubId=200210&RIN=1205-AB16"
response = requests.get(url)

# parse the html
html = BeautifulSoup(response.content)

# find all the <a> tags
a_tags = html.findAll('a', attrs={'class': 'pageSubNavTxt'})


def fetch_parent_tag(tags):
    # fetch the parent <td> tag of the first <a> tag
    # whose "previous sibling" is the <b>Legal Authority:</b> tag.
    for tag in tags:
        sibling = tag.findPreviousSibling()
        if not sibling:
            continue
        if sibling.getText() == 'Legal Authority:':
            return tag.findParent()

# now, just find all the child <a> tags of the parent.
# i.e. finding the parent of one child, find all the children
parent_tag = fetch_parent_tag(a_tags)
tags_you_want = parent_tag.findAll('a')

for tag in tags_you_want:
    print 'statute: ' + tag.getText()

Если это не совсем то, что вам нужно сделать, BeautifulSoup по-прежнему инструмент, который вы, вероятно, захотите использовать для просеивания html.

person Mark Gemmill    schedule 14.07.2012
comment
Спасибо Марк, это кажется полезным модулем. - person Emir; 14.07.2012

Там они предоставляют XML-данные, см. мой комментарий. Если вы считаете, что не можете загрузить столько файлов (или другому концу может не понравиться такое количество HTTP-запросов GET), я бы порекомендовал попросить их администраторов предоставить вам другой способ доступа к данным.

Я делал это дважды в прошлом (с научными базами данных). В одном случае сам размер набора данных не позволял загружать его; они выполнили мой SQL-запрос и отправили результаты по электронной почте (но ранее предлагали отправить по почте DVD или жесткий диск). В другом случае я мог бы сделать несколько миллионов HTTP-запросов к веб-сервису (и они были в порядке), каждый из которых извлекал около 1 КБ байт. Это заняло бы много времени и было бы довольно неудобно (требуя некоторой обработки ошибок, поскольку время ожидания некоторых из этих запросов всегда истекало) (и не атомарно из-за пейджинг). Мне прислали DVD.

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

person tiwo    schedule 20.07.2012