Python Urlib - 忽略 Unicode 错误
Python Urlib - Ignore Unicode Error
我正在构建网络爬虫,但遇到了问题。基本上,爬虫找到 的所有值,然后尝试系统地导航到所有这些相关链接。例如,如果在 http://example.com there was the links "home.html" and "about.html" the crawler would move through and try to request the base domain + the newly found domain (ex. http://example.com/home.html, http://example.com/about.html 的主页上)。
但是,在我的测试站点上,我将其设置为 。当 python 中的 urlib 函数尝试请求 .pdf 文件时,出现此错误:
有没有一种方法可以构建一个 try / except,如果发生这种情况会忽略 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
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
代码继续运行,但这是遇到错误的主要部分。有任何想法吗?我想这很容易解决。
我认为您只需在脚本底部添加一个 except UnicodeDecodeError:
就可以了。
要处理 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,而是使用 headers and/or 元标记,告诉您实际编码是什么。
正确执行此操作是 not trivial. and you might be happier using requests
而不是 urllib
,因为它具有所有内置逻辑(除了最后的 "heuristic" 步骤——但 BeautifulSoup
执行该部分) .
如果由于某种原因您不能使用 stdlib 之外的任何东西:
- 第一步很简单:
page.headers.get_content_charset()
。
- 最后一步 也 简单:如果您不知道编码,只需传递
BeautifulSoup
个字节,它将使用 "Unicode, damnit"启发式。
- 另一方面,解析
META
标签可能会很痛苦。您需要对二进制数据进行 soupify 并祈祷,或者使用 non-strict 错误处理解码为 ASCII 并对其进行 soupify,然后执行 soup.find_all('meta')
,并检查每个数据以查看它是否具有 http-equiv="Content-Type"
属性具有 charset
值,或 charset
属性,那么您可以将其用于 re-decode 和 re-soupify.
我正在构建网络爬虫,但遇到了问题。基本上,爬虫找到 的所有值,然后尝试系统地导航到所有这些相关链接。例如,如果在 http://example.com there was the links "home.html" and "about.html" the crawler would move through and try to request the base domain + the newly found domain (ex. http://example.com/home.html, http://example.com/about.html 的主页上)。
但是,在我的测试站点上,我将其设置为 。当 python 中的 urlib 函数尝试请求 .pdf 文件时,出现此错误:
有没有一种方法可以构建一个 try / except,如果发生这种情况会忽略 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
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
代码继续运行,但这是遇到错误的主要部分。有任何想法吗?我想这很容易解决。
我认为您只需在脚本底部添加一个 except UnicodeDecodeError:
就可以了。
要处理 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,而是使用 headers and/or 元标记,告诉您实际编码是什么。
正确执行此操作是 not trivial. and you might be happier using requests
而不是 urllib
,因为它具有所有内置逻辑(除了最后的 "heuristic" 步骤——但 BeautifulSoup
执行该部分) .
如果由于某种原因您不能使用 stdlib 之外的任何东西:
- 第一步很简单:
page.headers.get_content_charset()
。 - 最后一步 也 简单:如果您不知道编码,只需传递
BeautifulSoup
个字节,它将使用 "Unicode, damnit"启发式。 - 另一方面,解析
META
标签可能会很痛苦。您需要对二进制数据进行 soupify 并祈祷,或者使用 non-strict 错误处理解码为 ASCII 并对其进行 soupify,然后执行soup.find_all('meta')
,并检查每个数据以查看它是否具有http-equiv="Content-Type"
属性具有charset
值,或charset
属性,那么您可以将其用于 re-decode 和 re-soupify.