Python爬虫基础教程(9)Python标准库urllib.request模块之修改header:别让你的爬虫“裸奔”出门!urllib.request的‘易容术’大揭秘

别让你的爬虫“裸奔”出门!urllib.request的‘易容术’大揭秘

嘿,各位爬虫萌新们,有没有遇到过这种尴尬情况?你摩拳擦掌,写了几行代码,感觉即将成为数据江湖的侠客,结果一运行——HTTP Error 403: Forbidden?或者返回一堆乱码,甚至直接给你跳转到一个验证页面?

别慌,别怀疑人生,这大概率不是你的代码写错了,而是你的爬虫……它正在“裸奔”!

啥是“裸奔”? 就是你啥也没打扮,直接让urllib.request.urlopen()就冲出去了。在服务器看来,你这模样实在是太可疑了:一个没有User-Agent(用户代理)、没有Accept(接受内容类型)、没有任何“社会身份”的访问,不是脚本机器人是啥?不拦你拦谁?

今天,咱就来给咱们的爬虫兄弟好好上一堂“形象管理课”,教它如何用urllib.request模块,进行完美的“易容”,从人见人打的“脚本小弟”,伪装成彬彬有礼的“浏览器先生”。

第一幕:为啥要“易容”?Header到底是啥玩意儿?

想象一下这个场景:你走进一家高档餐厅(目标网站)。

  • “裸奔”的爬虫就像你穿着背心、裤衩、人字拖就进去了。服务员(服务器)一看,眉头紧锁:“这位客人,我们这儿有着装要求(反爬虫机制),请您离开(返回403错误)。”
  • 而伪装好的爬虫,则是西装革履,头发梳得一丝不苟。你一进门就微笑着说:“你好,我是一位用Chrome浏览器的普通用户,想看看你们的菜单(网页数据)。” 服务员一看,哎,正常客人,里面请!

这里你说的那句“自我介绍”,就是HTTP Header。它是HTTP协议里,客户端发给服务器的一串“附加信息”,用来告诉服务器这次请求的详细信息。

几个关键的“易容”道具(Header字段):

  1. User-Agent(用户代理)这是最重要的! 它告诉服务器你用的什么浏览器、什么操作系统。不带这个,就等于在喊“我不是人!”
  2. Referer:你是从哪个页面跳转过来的。有时候服务器会检查这个,防止你“空降”。
  3. *Accept-系列:告诉服务器你的客户端能接受什么类型的内容(文本、图片、JSON等)。
  4. Cookie:维持登录状态的神器,今天先不深入,但它非常重要。

urllib.request给了我们一个超级工具来携带这些信息,它就是——Request对象

第二幕:快速换装——使用Request对象

别再直接用urlopen(‘网址’)了!太原始了!我们要学会先“包装”请求。

基础版易容术:带上User-Agent

看代码,这是最核心的一步:

import urllib.request
import urllib.parse

# 目标网址(我们找个测试用的网站)
url = 'http://httpbin.org/user-agent'  # 这个网站会把你发送的User-Agent原样返回

# 1. 定义一个看起来像真实浏览器的Headers字典
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}

# 2. 创建Request对象,并把网址和headers丢进去
request = urllib.request.Request(url, headers=headers)

# 3. 用urlopen发送这个已经“包装”好的请求
response = urllib.request.urlopen(request)

# 4. 读取响应内容
html = response.read().decode('utf-8')

print(html)

运行结果,你会看到类似:

{
  "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}

看!服务器收到的,不再是什么Python-urllib/3.9,而是一个正经的Chrome浏览器标识!你的爬虫已经成功穿上了“西装”!

Request对象就像是一个快递订单urlopen只是负责派送。你在订单上写清楚了寄件人信息(Headers),快递员(urlopen)就会照单全送。

第三幕:精装修——动态添加与修改Header

有时候,我们创建Request对象时,可能忘了加某个Header,或者中途想改一下。怎么办?Request对象自带了一个叫 add_header() 的方法。

import urllib.request

url = 'http://httpbin.org/headers'

# 先创建一个Request对象,只带User-Agent
request = urllib.request.Request(url)
request.add_header('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15')

# 中途觉得,哎,我得告诉服务器我能接受json格式,再加一个!
request.add_header('Accept', 'application/json')

# 发送请求
response = urllib.request.urlopen(request)
print(response.read().decode('utf-8'))

这个方法非常灵活,就像是在出门前,又往西装口袋里塞了张名片(Accept头),让形象更完美。

第四幕:终极奥义——创建“全球形象顾问”(Opener和Handler)

上面的方法,一次请求包装一次,挺好。但如果你的爬虫需要像007一样,执行一系列连续任务(发送多个请求),每次都手动Requesturlopen,是不是有点麻烦?

这时候,你需要一个“全球形象顾问”——OpenerDirector(通常简称opener)。这个顾问会记住你的所有形象设定,并自动应用到你的每一次行动(请求)中。

怎么打造这个顾问?我们需要用到**HTTPHandlerbuild_opener**。

import urllib.request

# 定义一个强大的Headers,全方位伪装
headers = {
    'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    'Connection': 'keep-alive',
    'Upgrade-Insecure-Requests': '1',
}

# 1. 创建一个处理器(Handler),你可以理解为顾问的“大脑”
# 默认情况下,它什么也不做,但我们可以在创建时注入“人格”(headers)
opener = urllib.request.build_opener()

# 2. 把我们的headers以(键,值)对的形式,批量添加到opener中
opener.addheaders = list(headers.items())

# 3. 安装这个opener,让它成为全局默认的“顾问”。
# 从此以后,哪怕你用最简单的`urlopen(url)`,也会自动使用这个伪装好的opener!
urllib.request.install_opener(opener)

# 测试一下:现在直接用urlopen,看看是不是已经伪装好了?
response = urllib.request.urlopen('http://httpbin.org/user-agent')
print("使用全局Opener的结果:")
print(response.read().decode('utf-8'))

# 你也可以不安装为全局,而是单独使用这个opener
# response = opener.open('http://httpbin.org/headers')
# print(response.read().decode('utf-8'))

这种方法堪称“一劳永逸”。一旦设置好,你的整个脚本里的所有urllib.request请求,都会自动带上这全套Header,省心省力!

第五幕:完整实战——挑战一个“看脸”的网站

光说不练假把式,我们来个完整的例子。假设我们要抓取一个对Header有基本检查的网站(比如一些简单的新闻门户)。

import urllib.request
import urllib.error

def sophisticated_spider(url):
    """
    一个穿着得体的爬虫函数
    """
    # 精心准备的Header
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.59',
        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
        'Connection': 'keep-alive'
    }

    try:
        # 包装请求
        request = urllib.request.Request(url, headers=headers)
        
        # 发送请求并获取响应
        response = urllib.request.urlopen(request)
        
        # 判断请求是否成功(HTTP状态码为200)
        if response.status == 200:
            data = response.read()
            # 解码。有些网站可能是gbk编码,需要灵活处理
            try:
                html = data.decode('utf-8')
            except UnicodeDecodeError:
                html = data.decode('gbk')
            
            # 这里通常会用BeautifulSoup等库来解析html,提取数据
            # 我们今天就简单打印一下标题标签证明成功了
            if '<title>' in html:
                title_start = html.find('<title>') + 7
                title_end = html.find('</title>', title_start)
                print(f"页面标题:{html[title_start:title_end]}")
            else:
                print("成功获取页面内容,但未找到标题。")
            
            # 你可以将html保存到文件,或进行后续解析
            # with open('page.html', 'w', encoding='utf-8') as f:
            #    f.write(html)
            
        else:
            print(f"请求失败,状态码:{response.status}")

    except urllib.error.HTTPError as e:
        print(f"HTTP错误:{e.code} - {e.reason}")
    except urllib.error.URLError as e:
        print(f"URL错误:{e.reason}")
    except Exception as e:
        print(f"发生未知错误:{e}")

# 使用示例 (请替换成一个真实的、对Header不严苛的网站进行测试,避免给别人造成压力)
if __name__ == '__main__':
    target_url = 'https://httpbin.org/html'  # 一个返回示例HTML页面的网址
    print("爬虫开始工作...")
    sophisticated_spider(target_url)
    print("任务完成!")
尾声:易容师的自我修养(注意事项)
  1. User-Agent库:别总用一个User-Agent,可以准备一个列表,随机选一个用,降低被封风险。
  2. 适度原则:伪装是为了友好地获取公开数据,别去疯狂请求把人家的服务器搞垮了,那不道德,也可能违法。
  3. 进阶挑战:修改Header只是反爬虫的第一道门槛。后面还有Cookie、验证码、IP封锁、JavaScript渲染等大山等着你。那时候,你可能需要请出requestsSeleniumScrapy这些更专业的“特工工具包”。
  4. 编码问题:解码时(decode),如果utf-8报错,试试gbkgb2312,特别是国内的一些老网站。

好了,恭喜你!你的爬虫已经成功毕业,从“裸奔菜鸟”晋级为“初级易容师”了。记住,在数据的江湖里,有时候“以貌取人”是通行法则。穿上合适的“衣服”,你的爬虫之路会顺畅很多!

现在,就去给你的代码“换装”吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

值引力

持续创作,多谢支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值