我正在构建一个网络爬虫,我遇到了障碍。基本上,爬虫会找到<的所有值。 a href =“...”>然后尝试系统地导航到所有这些相关链接。例如,如果在http://example.com的主页上有链接“home.html”和“about.html”,则抓取工具将通过并尝试请求基本域+新发现的域(例如{{ 3}},http://example.com/home.html)。
然而,在我的测试网站上,我设置了一个< a href =“file.pdf”>。当python中的urlib函数尝试请求.pdf文件时,我收到此错误:
有没有办法可以构建一个try /,如果发生这种情况会忽略URL?这是我目前的相关代码:
def soupify(url):
"""
:param: URL string.
:return: HTML BeautifulSoup object as html.parser
Process: Requests website for HTML code. If it responds, converts the code into IO stream so that it can become a
Soup object.
"""
# Header info so that the web server does not deny the request
hdr = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11'}
req = urllib.request.Request(url, headers=hdr)
page = urllib.request.urlopen(req)
# This is to create in memory the HTML code of the page.
file = io.TextIOWrapper(page, encoding='utf-8')
fileContents = file.read()
soupObject = soup(fileContents, "html.parser")
return soupObject
然后,当我尝试实际访问URL后,会发生什么。
url = baseDomain + queue[0]
queueLength = len(queue)
print("Queue:", queueLength)
isError = False
# Exception handling when attempting to make a soup object.
try: fileContents = soupify(url)
except urllib.error.HTTPError: # If the website returns an HTTP error, such as a 404
inaccessibleSites += 1
isError = True
queue.pop(0)
except urllib.error.URLError: # If the website does not exist or does not have a valid URL
inaccessibleSites += 1
isError = True
queue.pop(0)
# Here is where I want to build an except to handle the bad codec but I am not sure where to start
代码继续运行,但这是导致错误的主要部分。有任何想法吗?我想这是一个简单的解决方案。
答案 0 :(得分:2)
要处理UnicodeDecodeError
,您执行与处理urllib.error.HTTPError
和urllib.error.URLError
相同的操作。
所以:
try:
fileContents = soupify(url)
except urllib.error.HTTPError: # If the website returns an HTTP error, such as a 404
inaccessibleSites += 1
isError = True
queue.pop(0)
except urllib.error.URLError: # If the website does not exist or does not have a valid URL
inaccessibleSites += 1
isError = True
queue.pop(0)
except UnicodeDecodeError: # If the website is not in UTF-8
inaccessibleSites += 1
isError = True
queue.pop(0)
或者,由于您实际上没有为这三个错误做任何不同的事情,您可以使用一个except
:
try:
fileContents = soupify(url)
except (urllib.error.HTTPError, # If the website returns an HTTP error,
urllib.error.URLError, # If the website does not exist or does not have a valid URL
UnicodeDecodeError): # If the website is not in UTF-8
inaccessibleSites += 1
isError = True
queue.pop(0)
但同时,你可能 想要在这里做的是停止假设每个网页都是UTF-8而是使用标题和/或元标记来告诉你编码实际上是什么
正确执行此操作是not trivial。使用requests
代替urllib
可能会更开心,因为它内置了所有逻辑(除了最终的"启发式"步骤 - 但BeautifulSoup
执行该部分)
如果由于某种原因你不能在stdlib之外使用任何东西:
page.headers.get_content_charset()
。BeautifulSoup
个字节,它就会使用" Unicode,该死的& #34;试探法。META
标签可能会很痛苦。您需要对二进制数据进行加密并交叉,或者使用非严格的错误处理解码为ASCII并对其进行解密,然后执行soup.find_all('meta')
,并检查每个数据以查看它是否具有{{1如果属性具有http-equiv="Content-Type"
值或charset
属性,则您可以使用该属性重新解码并重新充值。答案 1 :(得分:0)
我认为您只需在脚本底部添加except UnicodeDecodeError:
,就可以了。