我有一个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有什么区别?
答案 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