您的位置:首页 > 财经 > 产业 > Python 爬虫技巧:百度页面重定向的自动跟踪与处理

Python 爬虫技巧:百度页面重定向的自动跟踪与处理

2024/11/18 5:25:04 来源:https://blog.csdn.net/Z_suger7/article/details/140959057  浏览:    关键词:Python 爬虫技巧:百度页面重定向的自动跟踪与处理

python_00007.png
在网络爬虫的开发过程中,重定向是一个常见的现象,尤其是在访问大型网站如百度时。重定向可以是临时的,也可以是永久的,它要求爬虫能够自动跟踪并正确处理这些跳转。本文将探讨如何使用 Python 编写爬虫以自动跟踪并处理百度页面的重定向。

理解 HTTP 重定向

HTTP 重定向是服务器告诉客户端(如浏览器或爬虫)请求的资源现在位于另一个 URL。HTTP 状态码 301(永久移动)和 302(临时移动)是最常见的重定向状态码。

301 重定向

表示资源已被永久移动到新的 URL,爬虫应该更新其索引以使用新的 URL。

302 重定向

表示资源临时移动到新的 URL,爬虫可以继续使用原始 URL。

使用 Python urllib 处理重定向

Python 的 urllib 模块提供了处理 HTTP 请求的工具,包括自动处理重定向。然而,有时候我们需要更细粒度的控制,例如限制重定向次数或记录重定向历史。

自动处理重定向

urlliburlopen 函数会自动处理重定向,但默认情况下不提供重定向的详细信息。以下是一个示例,展示如何使用 urllib 自动处理重定向:

python
import urllib.requestdef fetch_url(url):try:response = urllib.request.urlopen(url)return response.read().decode('utf-8')except urllib.error.URLError as e:print(f"Failed to reach a server: {e.reason}")return None# 使用示例
content = fetch_url('http://www.baidu.com')

自定义重定向处理

为了更细粒度的控制,我们可以自定义重定向处理逻辑:

python
from urllib import request, errorclass RedirectHandler(request.HTTPRedirectHandler):def __init__(self, max_redirects=10):super().__init__()self.max_redirects = max_redirectsself.redirect_count = 0def http_error_302(self, req, fp, code, msg, headers):self.redirect_count += 1if self.redirect_count >= self.max_redirects:raise error.HTTPError(req.full_url, code, msg, headers, fp)return super().http_error_302(req, fp, code, msg, headers)def fetch_url_with_redirect_handling(url):opener = request.build_opener(RedirectHandler())request.install_opener(opener)try:with request.urlopen(url) as response:return response.read().decode('utf-8')except error.HTTPError as e:print(f"HTTP error: {e.code}")return Noneexcept error.URLError as e:print(f"URL error: {e.reason}")return None# 使用示例
content = fetch_url_with_redirect_handling('http://www.baidu.com')

持久连接

持久连接允许在一个 TCP 连接上发送多个 HTTP 请求和响应,减少了连接建立和关闭的开销。urllib 模块在 Python 3.6 之后默认支持 HTTP/1.1 的持久连接。

使用 http.client 实现持久连接

以下是一个使用 http.client 实现持久连接的示例:

import http.client
from urllib.parse import urlparse
from http.client import HTTPResponse# 代理服务器设置
proxyHost = "www.16yun.cn"
proxyPort = "5445"
proxyUser = "16QMSOML"
proxyPass = "280651"class PersistentHTTPConnection(http.client.HTTPConnection):def __init__(self, host, port=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, proxy_info=None):super().__init__(host, port, timeout)self.proxy_info = proxy_infodef connect(self):# 连接到代理服务器super().connect()if self.proxy_info:# 使用 Basic Auth 认证username, password = self.proxy_infocredentials = f"{username}:{password}"credentials = "Basic " + credentials.encode('utf-8').base64().decode('utf-8')self.sock.sendall(b"Proxy-Authorization: " + credentials.encode('utf-8'))class PersistentHTTPConnectionWithProxy(PersistentHTTPConnection):def __enter__(self):return selfdef __exit__(self, exc_type, exc_val, exc_tb):self.close()def fetch_with_persistent_connection(url, proxy_info=None):parsed_url = urlparse(url)conn = PersistentHTTPConnectionWithProxy(parsed_url.netloc, proxy_info=proxy_info)conn.connect()  # 连接到代理服务器conn.request("GET", parsed_url.path)response = conn.getresponse()if response.status == 200:return response.read().decode('utf-8')else:print(f"HTTP error: {response.status}")return None# 使用示例
content = fetch_with_persistent_connection('http://www.baidu.com', (proxyUser, proxyPass))

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com