Python - 传递URL与HTTPResponse对象

时间:2012-03-27 22:01:15

标签: python url beautifulsoup

我有一个URL列表,我想从中删除一个属性。新手到Python,请原谅。 Windows 7,64位。 Python 3.2。

以下代码有效。 pblist是一个由dicts组成的列表,其中包含键'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传递给BeautifulSoup中的urllib.request.urlopen并传递urllib.request.urlopen返回的HTTPResponse ojbect有什么区别?

1 个答案:

答案 0 :(得分:0)

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