Python - Передача URL-адресов против объекта HTTPResponse - PullRequest
1 голос
/ 28 марта 2012

У меня есть список URL-адресов, с которых я хочу очистить атрибут. Новичок в Python, поэтому, пожалуйста, извините. Windows 7, 64-битная. Python 3.2.

Следующий код работает. pblist - это список, состоящий из диктов, которые включают ключ 'short_url'.

for j in pblist[0:10]:
    base_url = j['short_url']
    if hasattr(BeautifulSoup(urllib.request.urlopen(base_url)), 'head') and \
        hasattr(BeautifulSoup(urllib.request.urlopen(base_url)).head, 'title'):
            print("Has head, title attributes.")
            try:
                j['title'] = BeautifulSoup(urllib.request.urlopen(base_url)).head.title.string.encode('utf-8')
            except AttributeError:
                print("Encountered attribute error on page, ", base_url)
                j['title'] = "Attribute error."
                pass

В следующем коде нет - например, в коде утверждается, что объект BeautifulSoup не имеет атрибутов заголовка и заголовка.

for j in pblist[0:10]:
        base_url = j['short_url']
        page = urllib.request.urlopen(base_url)
        if hasattr(BeautifulSoup(page), 'head') and \
            hasattr(BeautifulSoup(page).head, 'title'):
                print("Has head, title attributes.")
                try:
                    j['title'] = BeautifulSoup(urllib.request.urlopen(base_url)).head.title.string.encode('utf-8')
                except AttributeError:
                    print("Encountered attribute error on page, ", base_url)
                    j['title'] = "Attribute error."
                    pass

Почему? В чем разница между передачей URL-адреса urllib.request.urlopen в BeautifulSoup и передачей объекта HTTPResponse, возвращаемого urllib.request.urlopen?

1 Ответ

0 голосов
/ 28 марта 2012

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

Таким образом, во второй версии первый вызов BeautifulSoup(page) считывает все данные из page, а последующие вызовы больше не имеют данных для чтения.

Вместо этого вы можете сделать следующее:

page = urllib.request.urlopen(base_url)
page_content = page.read()
# ...
BeautifulSoup(page_content)
# ...
BeautifulSoup(page_content)

но даже это отчасти неэффективно. Вместо этого, почему бы просто не создать объект BeautifulSoup и передать его?

page = urllib.request.urlopen(base_url)
soup = BeautifulSoup(page)
# ...
# do something with soup
# ...
# do something with soup

Ваш код, модифицированный для использования одного супового объекта:

for j in pblist[0:10]:
        base_url = j['short_url']
        page = urllib.request.urlopen(base_url)
        soup = BeautifulSoup(page)
        if hasattr(soup, 'head') and \
            hasattr(soup.head, 'title'):
                print("Has head, title attributes.")
                try:
                    j['title'] = soup.head.title.string.encode('utf-8')
                except AttributeError:
                    print("Encountered attribute error on page, ", base_url)
                    j['title'] = "Attribute error."
                    pass
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...