Python爬虫基础之 Urllib

一、Urllib

1.爬虫概述

爬虫:网络爬虫,是一种按照一定规则,自动抓取互联网信息的程序或者脚本,其本质是模拟浏览器打开网页,获取网页中我们想要的数据。常用的百度、谷歌的搜索引擎也是一个爬虫,把互联网中的数据搜集组合起来便于用户检索。

注:爬虫并不是Python独有的,可以做爬虫的语言有很多例如:PHP, JAVA, C#, C++, Python,选择Python做爬虫是因为Python相对来说比较简单,而且功能比较齐全。

2.Urllib简介

Urllib 库,它是 Python 内置的 HTTP 请求库,也就是说我们不需要额外安装即可使用,它包含四个模块:

1.第一个模块 request,它是最基本的 HTTP 请求模块,我们可以用它来模拟发送请求,就像在浏览器里输入网址然后敲击回车一样,只需要给库方法传入 URL 还有额外的参数,就可以模拟实现这个过程了。

2.第二个 error 模块,即异常处理模块,如果出现请求错误,我们可以捕获这些异常,然后进行重试或其他操作,保证程序不会意外终止。

3.第三个 parse 模块是一个工具模块,提供了许多 URL 处理方法,比如拆分、解析、合并等的方法。

4.第四个模块是 robotparser,主要是用来识别网站的 robots.txt 文件,然后判断哪些网站可以爬,哪些网站不可以爬的,其实用的比较少。

简单来说:

1.urllib.request 负责请求;

2.urllib.error 异常处理模块;

3.urllib.parse url 负责解析;

4.urllib.robotparser 负责robots.txt文件的解析;

3.Urllib.request的基本使用

import Urllib.request
	url = 'http://www.baidu.com'	# 定义url
    
    response = urllib.request.urlopen(url)	# 模拟浏览器向服务器发送请求
    
    # print(type(response))	# 打印response的类型 
    
    # content = response.read() # 返回的是二进制字节码码
    
    # 利用decode('编码格式')将二进制字节码转换为字符串
    content = response.read().decode('utf-8')	# 接收内容
    
    print(content)
    

注:URL是对互联网上得到的资源的位置和访问方法的一种简洁表示,是互联网上标准资源的地址。 简单地说URL就是web地址,俗称“网址”。

打印response 的类型为 <class ‘http.client.HTTPResponse’>

1.http.client:HTTP 协议客户端;

2.HTTPResponse :

​ HTTPResponse实例表示客户端发出请求之后,服务端的 HTTP 响应,包含 http code、响应头、响应内容的。HTTPResponse继承自io.BufferedIOBase,拥有 IO 字节流的相关操作方法。HTTPResponse对象支持with上下文管理器,在with语句退出时会自动调用其close()方法。调用HTTPConnection.close()方法关闭套接字连接时也会自动调用HTTPResponse.close()。

4.response的类型和方法

这里的response是指 urllib.request.urlopen(url) 的返回值,实际上,reponse这个词可以换成任何一个,不过对于爬虫来说,一般用这个词代表request的返回值。

import urllib.request

url = 'http://www.baidu.com'

# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(url)

# response的类型
# 运行下个语句可知,response的类型是HTTPResponse
# print(type(response))

# 按照一个字节一个字节的方式去读
# content = response.read()
# print(content)

# 返回多少个字节
# content = response.read(5)  读取5个字节
# print(content)

# 读取一行
# content = response.readline()
# print(content)

# 按行读取所有内容
# content = response.readlines()
# print(content)

# 返回状态码,如果是200,那么就证明代码逻辑没有问题
# print(response.getcode())

# 返回url地址
# print(response.geturl())

#获取状态信息
print(response.getheaders())

5.urlretrieve()下载

urllib.request.urlretrieve(url, filename);

url代表的是下载的路径, filename代表文件的名字。

参数可以是赋值的形式,也可以直接写值。

eg:赋值的形式:

urllib.request.urlretrieve(url=url, filename=filename)

下面给出具体的代码示例,以下载网页源码为例:

import urllib.request

url_page = 'http://www.baidu.com'

urllib.request.urlretrieve(url_page, 'baidu.html')

注:根据下载内容的不同,文件名称的后缀也要做出相应的变化。

eg:网页源码-> .html

​ 图片 -> .jpg

​ 视频 -> .mp4

关于参数赋值和直接写值情况的选择:

​ 若函数参数的顺序不乱,且两参数中间无其它参数,则可采用直接写值的写法。

​ 若参数顺序打乱或顺序不乱两参数中间预留有其它参数(但没有用到)的情况需要赋值。

6.请求对象的定制

url的组成:

eg: https://cn.bing.com/search?q=周杰伦

协议:   http/https(更加安全)

主机(指域名):   www.baidu.com

​ 端口号: http: 80 https: 443 mysql:3306 oracle:1521 redis:6379 mongodb:27017

​ 路径:search

​ 参数:q=周杰伦

​ 锚点: 锚记/锚点是网页制作中超级链接的一种,又叫命名锚记。它就像定位器一样是一种页面内的超级链接,可以迅速跳到某个节点。

在爬取某些网页时,很有可能会遇到反扒,所以我们需要伪装自己,尽量将自己伪装成正常的浏览器访问服务器。这时候就需要用到UA:User Agent中文名为用户代理,简称UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU类型、浏览器及版本、浏览器内核、浏览器渲染引擎、浏览器语言、浏览器插件等。

而UA是需要放到请求头中的

eg:

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36'
}

headers是字典类型的,但urllib.request.urlopen()不能接受字典类型的参数,所以需要用到请求对象的定制即:urllib.request.Request(url=url, headers=headers)

返回的对象一般命名为request,完整为: request = urllib.request.Request(url=url, headers=headers)

request 的类型为 <class ‘urllib.request.Request’>

爬取百度的完整代码示例:

import urllib.request

#定义url
url = 'https://www.baidu.com'

#请求头
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36'
}

#请求对象的定制,因为默认参数url和headers中还有data,所以采用赋值的方式
request = urllib.request.Request(url=url, headers=headers)

#模拟浏览器发送请求
response = urllib.request.urlopen(request)

#解析内容
content = response.read().decode('utf-8')

#输出获取的内容
print(content)

7.urllib_get请求

GET请求一般用于我们向服务器获取数据 。

7.1quote()方法

当我们想要爬取搜索结果页面时:

在这里插入图片描述

我们通过搜索结果的页面复制的url是 https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=%E5%91%A8%E6%9D%B0%E4%BC%A6

可以看到 wd=周杰伦 已经被自动转换为Unicode码的形式,可以通过更换wd后的值获取任意搜索结果的页面,例如:wd=毛不易 就可以得到毛不易搜索页面的结果,不过这就碰到了一个问题,那就是网页不会识别中文,所以需要将中文毛不易转换为Unicode码值,这时就需要用到quote()方法了。

以获取毛不易搜索结果页面源码为例:

import urllib.request
# 导入此包以使用中文转换为Unicode码的函数
import urllib.parse

#原始url
base_url = 'https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd='
#中文转化为Unicode
name = urllib.parse.quote('毛不易')

url = base_url + name

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36'
}

request = urllib.request.Request(url=url, headers=headers)

response = urllib.request.urlopen(request)

content = response.read().decode('utf-8')

print(content)

7.2urlencode()方法

与quote()方法类似,不同之处是urlencode()可以将多个中文转化为Unicode

以周杰伦搜索页面为例

import urllib.request
import urllib.parse

base_url = 'https://www.baidu.com/s?'

data = {
    'wd': '周杰伦',
    'sex': '男',
    'location': '中国台湾省'
}

#多个中文转Unicode
data = urllib.parse.urlencode(data)

url = base_url + data

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36'
}

#请求对象的定制
request = urllib.request.Request(url=url, headers=headers)

#模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)

content = response.read().decodea('utf-8')

print(content)

8.urllib_post请求

之前说过Request请求对象的里有data参数,它就是用在POST里的,我们要传送的数据就是这个参数data,data是一个字典,里面要匹配键值对。

以获取百度翻译为例

import urllib.request
import urllib.parse

# 这个网址是在sug headers中的Request URL(内容是单词的翻译)
# 如果复制翻译网址栏的url那么爬取的就不是单词翻译,具体表现获取的数据是否为json类型
url = 'https://fanyi.baidu.com/sug'

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36'
}

data = {
    'kw': 'spider'	# 爬取百度翻译中spider的单词解释
}

# post的请求的参数 必须要进行编码
data = urllib.parse.urlencode(data).encode('utf-8')

# post的请求的参数是不会拼接在url后面的,而是需要放在请求定制的参数中
request = urllib.request.Request(url=url, data=data, headers=headers)

resposne = urllib.request.urlopen(request)

# 返回的json数据,需要解析
content = response.read().decode('utf-8')
# print(type(content)) <class 'str'>	json字符串

import json

obj = json.loads(content)   #json字符串变成python字典
# print(type(obj))	<class 'dict'> 字典类型
print(obj)

在使用百度翻译时若想要翻译英文,就需要切换到英文输入法,否则在network中找不到name为 sug 的选项。

为什么进行encode(utf-8)的编码?

因为请求对象定制中,urllib.request.Request(url=url, data=data, headers=headers)中参数data的数据类型要求是bytes类型,所以需要惊醒encode()编码(对应的解码时 decode())。

如何看出是json字符串?

因为返回的数据格式是{key:value, key:[{…}]},即json数据的格式。

json字符串与json对象

(1)JSON字符串

JSON字符串与普通的字符串没有任何特殊的地方,但是之所以称为JSON字符串是因为,这个字符串符合json数据的格式

(2)JSON对象

JSON对象主要是在JavaScript的说法。在面向对象编程中,类的实例化叫做对象,对象拥有不同的属性,键值对就是对象的属性和值。

** python json模块的四种方法**

  • loads():将json数据转化成dict数据
  • dumps():将dict数据转化成json数据
  • load():读取json文件数据,转成dict数据
  • dump():将dict数据转化成json数据后写入json文件

9.get请求和post请求的区别

9.1两种请求的简单对比

在客户机和服务器之间进行请求-响应时,两种最常被用到的方法是:GET 和 POST。

GET - 从指定的资源请求数据;

POST - 向指定的资源提交要被处理的数据;

选项GETPOST
后退按钮/刷新无害数据会被重新提交(浏览器应该告知用户数据会被重新提交)。
书签可以被收藏为书签不可以被收藏为书签
缓存能被缓存不能被缓存
编码类型application/x-www-form-urlencodedapplication/x-www-form-urlencoded或multipart/form-data。为二进制数据使用多重编码。
历史参数保留在浏览器历史中参数不会保留在浏览器历史中
对数据长度的限制只允许ASCII字符没有限制,也允许二进制数据
安全性与POST相比,GET的安全性较差,因为发送的数据是URL的一部分POST比GET更安全,因为参数不会被保存在浏览器历史或web服务器日志中。
可见性数据在URL中对所有人都是可见的数据不会显示在URL中

9.2抓取方式的异同

(1)Get方式

GET方法是最常见也是最简单的,HTTP默认的请求方法就是GET。

一般用于我们向服务器获取数据,可以直接将URL输入,不需要其它的转换,即所有需要请求的信息都包含在URL中。

* 没有请求体

* 数据必须在1K之内!

* GET请求数据会暴露在浏览器的地址栏中

常用的操作:

① 在浏览器的地址栏中直接给出URL,那么就一定是GET请求;

② 点击页面上的超链接也一定是GET请求;

③ 提交表单时,表单默认使用GET请求,但可以设置为POST;

get请求就是在url后面以拼接方式传参,但是如果参数是中文时需要转码处理,否则会报错。

(2)Post方式

post用于将数据发送到服务器来创建/更新资源。

通过post发送到服务器的数据存储在 HTTP 请求的请求主体中:

POST /test/demo_form.php HTTP/1.1
Host: w3school.com.cn
name1=value1&name2=value2

post要获取的内容只靠网址是不能获取到的,需要提交一些额外的信息。

这种信息在不同的网页中发挥不同功能,例如在查询天气的网页,可能就是要输入城市信息;在登录某些网页时,又是账号和密码的载体。

post请求:

① 数据不会出现在地址栏中

② 数据的大小没有上限

③ 有请求体

④ 请求体中如果存在中文,会使用URL编码!

一般HTTP请求提交数据,需要编码成URL编码格式,然后做为URL的一部分,或者作为参数传到Request对象中。

特殊点:
Request请求对象里有data参数,而post请求通过Request对象中的data属性来传参,用来存放请求体数据。
data是一个字典,里面要有匹配键值对。

10.urllib_Ajax

AJAX 是 Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)的缩写 。

AJAX 是与服务器交换数据并更新部分网页的艺术,在不重新加载整个页面的情况下,对网页的某部分进行更新。 传统的网页(不使用AJAX)如果需要更新内容,必需重载整个网页。

有些网页内容使用AJAX加载,只要记得,AJAX一般返回的是JSON,直接对AJAX地址进行post或get,就返回JSON数据了。

简而言之,AJAX和平时爬取的方式没有太大的不同,只是下载多页数据时,url可能只变化了一部分,只要改变这一部分就能达到更换另一个网页的作用。

eg:以豆瓣电影排行榜的前三页url为例

https://movie.douban.com/j/chart/top_list?type=5&#interval_id=100%3A90&action=&start=0&limit=20

https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&start=20&limit=20

https://movie.douban.com/j/chart/top_list?type=5&#interval_id=100%3A90&action=&start=40&limit=20

三个网页的url的格式相同,唯一的不同之处就是start=’ '这个属性,所以可以利用这个特性进行多个网页的下载。

10.1Ajax的get请求

和之前的爬虫下载数据相似,不同之处是这里是实现多页爬取。

以下载豆瓣排行榜的前十页数据为例;

import urllib.request
import urllib.parse

# 将各部分封装成方法

# 请求对象的定制
def create_request(page):
    base_url = 'https://movie.douban.com/j/chart/top_list?				type=5&interval_id=100%3A90&action=&'

	# 接在base_url后的属性
	data = {
    	start = (page-1) * 20, # start和页数的关系
    	limit = 20	# 一页有二十条数据
	}
    
    # 转换为Unicode编码
    data = urllib.parse.urlencode(data)	# get请求不需要encode('utf-8')编码
    
    url = base_url + data
    
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 	(KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36'
    }

        # 请求对象的定制
    request = urllib.request.Reqeust(url=url, headers=headers)

	return request

# 获取返回内容
def get_content(request):
    response = urllib.request.urlopen(reqeust)
    content = response.read().decode('utf-8')

    return content

# 将数据保存到文件中
def down_load(page, content):
    with open('douban' + str(page) + '.json', 'w', encoding='utf-8') as fp:
        fp.write(content)
        
# 调用函数,下载数据
# 程序的入口
if __name__ == 'main':
    start_page = int(input('请输入起始页码:'))
    end_page = int(input('请输入结束页码:'))
    
    # range(a, b) 左闭右开
    for page in range(start_page, end_page+1):
        # 通过for循环对每一页进行请求对象的定制
        request = create_request(page)
        # 获取响应的数据
        content = get_content(request)
        # 下载数据到文件中
        down_load(page, content)

if name == ‘main’:的意义:
一个python文件通常有两种使用方法,第一是作为脚本直接执行,第二是 import 到其他的 python 脚本中被调用(模块重用)执行。因此 if name == ‘main’: 的作用就是控制这两种情况执行代码的过程,在 if name == ‘main’: 下的代码只有在第一种情况下(即文件作为脚本直接执行)才会被执行,而 import 到其他脚本中是不会被执行的。

10.2Ajax的post请求

以肯德基官网为例

import urllib.request
import urllib.parse

def create_reqeust(page):
	base_url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname'
	
	data = {
        'cname': '北京',
        'pid': '',
        'pageIndex': page,
        'pageSize': '10',
	}
	
	data = urllib.parse.urlencode(data).encode('utf-8')
	
	headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36'
    }
    
    request = urllib.request.Request(url=base_url, data=data, headers=headers)
    
    return request
	
def get_content(reqeust):
    response = urllib.request.urlopen(reqeust)
    content = response.read().decode('utf-8')
    
    return content

def down_load(page, content):
    with open('kfc_' + str(page) + '.json', 'w', encoding='utf-8') as fp:
        fp.write(content)

if __name__ == 'main':
    start_page = int(input("请输入起始页码:"))
    end_page = int(input("请输入结束页码:"))

    for page in range(start_page, end_page + 1):
        # 请求对象定制
        request = create_request(page)
        # 获取网页源码
        content = get_content(request)
        # 下载
        down_load(page, content)

Ajax get请求和post请求的不同之处也就是urllib_get请求和urllib_post请求的不同之处。

11.异常

当代码出现异常时,捕捉这个异常,避免程序遇到异常而崩溃。

利用错误的url进行爬虫访问,从而捕捉异常

import urllib.request
import urllib.error

url = 'https://www.nibuhao.com'

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36'
}

try:
    request = urllib.request.Request(url=url, headers=headers)
    response = urllib.request.urlopen(request)
    content = response.read().decode('utf-8')
    print(content)
except urllib.error.HTTPError:
    print("系统正在升级......")
except urllib.error.URLError:
    print("系统正在升级......")

当 try:代码块出现错误时,将会捕捉异常,然后输出“系统正在升级”。

12.Cookie登录

12.1关于Cookie

(1)Cookie是什么?

  1. Cookie 是浏览器访问服务器后,服务器传给浏览器的一段数据。
  2. 浏览器需要保存这段数据,不得轻易删除。
  3. 此后每次浏览器访问该服务器,都必须带上这段数据。

(2)Cookie的两个作用

  1. 识别用户登录
  2. 记录用户操作历史

12.2Cookie登录实例

下面以微博的Cookie登录为例:

import urllib.request

url = 'https://weibo.com/set/index'

# cookie    中携带着你的登录信息,如果有登录之后的cookie,那么我们就可以携带着cookie进入到任何页面
# referer   判断当前路径是不是由上一个路径进来的 一般情况下是做图片的防盗链
headers = {
    'cookie': 'PC_TOKEN=b8f7fc90b0; XSRF-TOKEN=b3l2PGnCDcoXHxTywucpnojA; SUB=_2A25JFErhDeThGeFN4lQX9CfNyTqIHXVqYDsprDV8PUNbmtAGLXndkW9NQ6TeAaBTHJqirM75ZCUBwjMaiU_P_qC2; SUBP=0033WrSXqPxfM725Ws9jqgMF55529P9D9Wh-Eo.u-BUA.hSDZlWi_0fj5JpX5KzhUgL.FoM01KqcSh.peoq2dJLoIp7LxKML1KBLBKnLxKqL1hnLBoMNe0.cSoB4eKzc; ALF=1710321201; SSOLoginState=1678785201; WBPSESS=d4xMu9nMFhY85YGY8BTO1g9EOrtW0yuonZm_34TC4IY9qWQIcXbFzn9FvhQhhMUxJQIAQDk677YrrNdq3i9wvhg_h3h0ZFxWvy75Ve_2HkGsyQ1IgoePm_vMWW-DUrIUY1LzJ55up6dRcEzYs9rPDQ==',
    'referer': 'https: //weibo.com/newlogin?tabtype=weibo&gid=102803&openLoginLayer=0&url=https%3A%2F%2Fweibo.com%2F',
    'user-agent': ' Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36',
}

# 请求对象的定制
request = urllib.request.Request(url=url, headers=headers)
# 模拟浏览器向服务器发送数据
response = urllib.request.urlopen(request)
# 获取响应的数据
content = response.read().decode('utf-8')

with open('weibo.html', 'w', encoding='utf-8') as fp:
    fp.write()

13.handler处理器

handler处理器的作用:
首先简单介绍一下handler处理器:handler处理器是继urlopen()方法之后又一种模拟浏览器向服务器发起请求的方法或技术。
它的意义在于使用handler处理器,能够携带代理ip,这为对抗反爬机制提供了一种策略(很多的网站会封掉短时间多次访问的ip地址)。

13.1 handler处理器的基本使用

例:使用handler处理器获取百度源码

import urllib.request

url = 'https://www.baidu.com'

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36'
}

request = urllib.request.Request(url=url, headers=headers)

response = urllib.request.urlopen(request)

content = response.read().decode('utf-8')

with open('baidu01.html', 'w', encoding='utf-8') as fp:
    fp.write(content)

13.2代理

(1)为什么要使用代理ip

随着信息的越来越庞大,获取数据的途径也不断增多,各个渠道都不会让使用者轻易的采集到本网的信息,而通过ip访问的频率可以对该ip进行判断,是否属于脚本机器在用,从而进行拦截,导致使用者不能采集该网站的信息。

(2)代理ip的来源

目前免费的ip来源有很多,比如: 站大爷 快代理 芝麻代理 等这些每日提供一些免费的ip网站,也可以进行注册长期使用。 另外,我们也可以手动去采集一些ip,通过脚本自动判断该ip是否可用,加入到ip池中。

这里以使用代理爬取ip查询网为例:

import urllib.request

url = 'http://www.ip138.com/'

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36'
}

request = urllib.request.Request(url=url, headers=headers)

# 模拟浏览器访问服务器
# response = urllib.request.urlopen(request)
# 需要代理的ip
proxies = {
    'http': '182.139.110.52:9000'
}

# handler build_opener open
# handler 的参数是需要代理的ip(以字典的形式存在)
handler = urllib.request.ProxyHandler(proxies=proxies)

opener = urllib.request.build_opener(handler)

response = opener.open(request)

# 获取响应信息
content = response.read().decode('utf-8')

# 保存
with open('dali.html', 'w', encoding='utf-8') as fp:
    fp.write(content)

注:代理ip很有可能会失效,所以测试运行可能会不正确

13.3代理池

创建一个含有多个代理ip的字典列表,利用随机函数获取其中任意一个代理ip以达到换区不同ip爬取数据的目的

如:

import request
import random

# 代理池
proxies_pool = [
    {'http': '118.24.219.151:134222'},
    {'http': '118.24.219.151:134333'},
]

# 获取其中一个代理 
proxies = random.choice(proxies_pool)




# 需要代理的ip
proxies = {
    'http': '182.139.110.52:9000'
}

# handler build_opener open
# handler 的参数是需要代理的ip(以字典的形式存在)
handler = urllib.request.ProxyHandler(proxies=proxies)

opener = urllib.request.build_opener(handler)

response = opener.open(request)

# 获取响应信息
content = response.read().decode('utf-8')

# 保存
with open('dali.html', 'w', encoding='utf-8') as fp:
    fp.write(content)

注:代理ip很有可能会失效,所以测试运行可能会不正确

  • 39
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

向之 所欣

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值