数据科学、数据分析、人工智能必备知识汇总-----Python爬虫-----持续更新:https://blog.csdn.net/grd_java/article/details/140574349
文章目录
1. 基本使用 2. 请求对象的定制 3. 编解码 1. get请求方式:urllib.parse.quote() 2. urllib.parse.urlencode()
4. post请求方式
5. ajax 1. get请求 2. 如何爬取多页数据 3. post请求
6. 异常URLError\HTTPError 7. cookie登录 8. handler处理器 1. Handler处理器基本使用 2. 代理 3. 代理池
1. 基本使用
本库无需用pip安装,是python本身自带的库,可以直接使用
进入百度,查看网页源码 这就是我们要获取的数据
首先我们先导包,我们需要用urllib模块的request 之后我需要用request中的urlopen函数访问对应url,并返回一个响应体,我们将其保存到response变量中 有了响应体对象后,通过read方法,将源码数据读取出来。上图中我们可以看到,确实读取出来了,但是是以b'
开头的,表示读取的是字节形式的二进制文件,我们会发现读取的数据都不是正常用户可以看懂的字符,而是十六进制编码
response服务器返回的数据解析,返回结果乱码的原因
response的数据类型是HttpResponse 我们需要将返回的数据由字节码转为我们能看懂的字符串,也就是解码decode操作,因为response自动进行了字符串转字节码,也就是编码encode操作 responose对象常用的函数
read( )
readline( )
readlines( )
getcode( )
geturl( )
getheaders( )
urllib. request. urlretrieve( )
我们可以在页面源码中,看到它的编码格式是utf-8
所以我们只需要对其进行utf-8格式的解码即可
'''导包(start)'''
import urllib. request;
'''导包(end)'''
url = "http://www.baidu.com" ;
response = urllib. request. urlopen( url) ;
content = response. read( ) . decode( 'utf-8' ) ;
print ( content) ;
urllib.request.urlretrieve()下载
此函数有两个参数,url表示要下载的内容的url地址,而filename表示下载完成后,我们要保存的地址和文件类型(文件后缀名)
下载网页:我们将百度首页的html文件,下载到当前文件夹的百度.html文件中
'''导包(start)'''
import urllib. request;
'''导包(end)'''
url = "http://www.baidu.com" ;
response = urllib. request. urlretrieve( url, "百度.html" ) ;
下载图片
因为我们现在还没有学到后面的知识,所以我们先手动获取一张图片的地址 只需要将函数的url参数换为图片的地址即可
'''导包(start)'''
import urllib. request;
'''导包(end)'''
url = "https://wxls-cms.oss-cn-hangzhou.aliyuncs.com/online/2024-04-18/218da022-f4bf-456a-99af-5cb8e157f7b8.jpg" ;
response = urllib. request. urlretrieve( url, "图片.jpg" ) ;
下载视频
还是找到一个视频(我们这里初学者,爬取时不要去找什么类似哔哩哔哩这样需要特殊处理的,我们就找一些简单的,直接用url可以爬取的,例如好看视频的),按下f12,选中视频控件,然后双击src中的视频路径,将其复制下来 然后就可以通过url下载到这个视频
'''导包(start)'''
import urllib. request;
'''导包(end)'''
url = "https://vdept3.bdstatic.com/mda-qdqxvr04ju7kwxez/cae_h264/1714102071853507436/mda-qdqxvr04ju7kwxez.mp4?v_from_s=hkapp-haokan-hbe&auth_key=1721564882-0-0-26db109d9d14804c8ba64ac44d474da6&bcevod_channel=searchbox_feed&pd=1&cr=0&cd=0&pt=3&logid=1682548574&vid=2405378101862107884&klogid=1682548574&abtest=101830_2-102148_2-17451_1"
response = urllib. request. urlretrieve( url, "视频.mp4" ) ;
2. 请求对象的定制
User Agent(用户代理):简称UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等
这是我们爬虫的第一道大关,简称UA校验,简单来说,如果我们不做特殊处理,他能识别到我们是假数据,而不是真实的用户,从而进行反爬
为了解决这个问题,我们需要进行伪装,获取正确的UA
如果不操作UA,直接访问https://www.baidu.com,就会被反爬
可以看到,我没有设置UA,爬取的数据是反爬处理过的数据,不是我们想要的
打开我们想要爬取的url,按下f12,进入network,然后刷新页面,在network中找到对应url请求,在请求头中,找到UA
复制UA,存放到python代码的字典中,注意,字典的名字并不硬性要求为headers,这里只是为了代码可读性而起名为headers
有了headers后,我们就可以用url和headers定制一个请求对象,也就是Request请求对象
有了这个对象,我们访问指定url时,直接使用这个request对象即可,可以发现,爬取到了想要的数据,而不是反爬处理的数据
'''导包(start)'''
import urllib. request
'''导包(end)'''
url = "https://www.baidu.com"
headers = { "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0" }
request = urllib. request. Request( url, headers= headers)
response = urllib. request. urlopen( request)
print ( response. read( ) . decode( "utf8" ) )
3. 编解码
1. get请求方式:urllib.parse.quote()
我们请求数据时,使用的是Unicode编码(也有例外),例如我们百度周杰伦时
url应该是https://www.baidu.com/s?wd=%E5%91%A8%E6%9D%B0%E4%BC%A6,其中%E5%91%A8%E6%9D%B0%E4%BC%A6是周杰伦的Unicode编码 而不是https://www.baidu.com/s?wd=周杰伦
我们不知道某些字符的Unicode编码怎么办呢?就可以使用urllib.parse.quote()函数,这个函数会将字符转为Unicode编码
urllib. parse. quote( "周杰伦" )
将需要使用Unicode编码的部分,全部使用quote函数生成,然后拼接
'''导包(start)'''
import urllib. request
import urllib. parse
'''导包(end)'''
url = "https://www.baidu.com/s?wd="
paras = urllib. parse. quote( "周杰伦" )
url+= paras
headers = { "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0" }
request = urllib. request. Request( url= "url" , headers= headers)
response = urllib. request. urlopen( request)
print ( response. read( ) . decode( "utf8" ) )
2. urllib.parse.urlencode()
当只有一个参数的时候,自然可以使用urllib.parse.quote()来解决 但是有多个参数呢?总不能一个个拼接吧 因此,urllib.parse.urlencode()就可以一次性转多个参数
'''导包(start)'''
import urllib. request
import urllib. parse
'''导包(end)'''
url = "https://www.baidu.com/s?"
data = { "wd" : "周杰伦" , "sex" : "男" }
paras = urllib. parse. urlencode( data) ;
url+= paras
print ( url)
4. post请求方式
1. 基本使用
进入百度翻译进行抓包,我们输入单词spider,可以发现,每输入一个字母都会进行Post请求,返回文件时sug,里面我们请求的表单,就是我们输入的单词
而响应体中,就是搜索到的翻译
一定要找对接口,这是爬虫的一大难点,如果无法找到正确的接口,就无法获取正确的数据
所以我们现在就有了爬虫的目标,url是https://fanyi.baidu.com/sug,请求方式是Post,请求参数是"kw":“spider”
注意,Post请求需要额外提交表单,也就是代码中的data字典。所白了和get请求不同,参数不是拼接在url的?后面,而是需要放到请求体的data中 data需要编码,首先urlencode将其编为Unicode,然后进行encode编码,编为utf-8 如果返回的是json数据,需要用json.loads函数进行转换才能不乱码
'''导包(start)'''
import urllib. request
import urllib. parse
import json
'''导包(end)'''
url = "https://fanyi.baidu.com/sug"
data = { "kw" : "spider" }
headers = { "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, likeGecko) Chrome/74.0.3729.169 Safari/537.36" }
data = urllib. parse. urlencode( data) . encode( "utf-8" )
request = urllib. request. Request( url= url, data= data, headers= headers)
response = urllib. request. urlopen( request)
content = response. read( ) . decode( "utf-8" )
print ( "直接输出会乱码" , content)
obj = json. loads( content)
print ( "转为json数据输出即可" , obj)
2. 处理第二种反爬手段
依然是百度翻译,只不过这次我们前往旧版本进行抓包,的抓包是https://fanyi.baidu.com/v2transapi?from=en&to=zh这个,它里面是单词更加详细的释义
它的请求表单更多
我们直接复制出来的数据是不规范的 我们通过一些文本工具,例如Notepad++来进行正则表达式的查找和替换 (.*) (.*)代表前面有若干个任意字符,后面有若干个任意字符,中间是一堆空格(直接复制原数据中间的空格)
,“\1”:\2表示替换为前面第一个小括号匹配到的值加双引号,中间替换为冒号
"from" : "en"
"to" : "zh"
"query" : "spider"
"simple_means_flag" : "3"
"sign" : "63766.268839"
"token" : "f1ebb176f73e77bc705c404803d693c0"
"domain" : "common"
"ts" : "1721619631760"
会发现被反爬了,只要被反爬,就考虑是不是他需要的东西我们没有给够
找到它的请求头 用文本软件改成key:value格式 放到代码的headers中,但是注意要将"Accept-Encoding":"gzip, deflate, br, zstd"注释掉,因为这句指定了编码格式,这里没有我们常用的utf-8格式
不将其注释掉会报这个错误 所以一定要注释掉
然后就可以爬到数据了
'''导包(start)'''
import urllib. request
import urllib. parse
import json
'''导包(end)'''
url = "https://fanyi.baidu.com/v2transapi?from=en&to=zh"
data = { "from" : "en" ,
"to" : "zh" ,
"query" : "spider" ,
"simple_means_flag" : "3" ,
"sign" : "63766.268839" ,
"token" : "f1ebb176f73e77bc705c404803d693c0" ,
"domain" : "common" ,
"ts" : "1721619631760" }
headers = { "Host" : "fanyi.baidu.com" ,
"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0" ,
"Accept" : "*/*" ,
"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" ,
"Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8" ,
"Acs-Token" : "1721545207246_1721619631762_cdhky/lsyn0MwcIYubxg6g+yGB7DWVkvHHhzEF4G/zcEHCTNSb+RWz1TzDIehhT0nRMmJ9iOG0UTlCwvejzWeFbqDj0oiIHda9ly0lnIom+SdYR9JWNykRa5+vLO2b5OOpNmeq7DzPRxGnhopulH0pTglWMPVnViHVFDQI5dKr3/IXBRVuAmdI3Be0YchzL49xTKBc2T46mceMQXmYBsRKMc7VJg+/+yMSqPPD5ukSCJ+ulvWC6cVgzdbyg3hXuOK6NgROzB1BB2PdzzTBrhRVWS/iOKWwcB1y1/YmMrVGWavgMMYB+IYqm8wp0pB00qCD1/RXRyn+tlWHhHyUsmsyQmFg5YRyesvTHE08RE+KRRcGAGQ07jtfRAeOKqzHlVihlaYs8xaqcyoMi2ihGIHpq0gUB4xV2R2Og+5d2dzcUuVCUwTknsvHTiKkci3QKFK8VVKHQqGzBfab+JYgZfTA==" ,
"X-Requested-With" : "XMLHttpRequest" ,
"Content-Length" : "134" ,
"Origin" : "https://fanyi.baidu.com" ,
"Connection" : "keep-alive" ,
"Referer" : "https://fanyi.baidu.com/" ,
"Cookie" : 'BIDUPSID=014FB2528D0EFCB53D0516AA9DDB229D; PSTM=1708246679; H_PS_PSSID=60359_60465_60492_60502; BAIDUID=014FB2528D0EFCB53D0516AA9DDB229D:SL=0:NR=10:FG=1; BDUSS=25VSy16NGhRV0xIfk5Kcy02SVdPaDZBWW9CcUNTNkM5UFdPZzJXTmthQn5kZnBsRVFBQUFBJCQAAAAAAAAAAAEAAAC9HTU-ztLM~czs0uIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH~o0mV~6NJlT; H_WISE_SIDS=60359_60465_60492_60502; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; ZFY=Qxrlg:B2RssHj4jywgOL:BJKmhUwoOwa7GUA2JeI:BD0Xc:C; BA_HECTOR=81a48425a401212l212h202l8i6npi1j9pgid1u; RT="z=1&dm=baidu.com&si=d748cf44-d8fb-4cf8-bfe9-88bf5213250c&ss=lywevcbe&sl=a&tt=goe&bcn=https%3A%2F%2Ffclog.baidu.com%2Flog%2Fweirwood%3Ftype%3Dperf&ld=yve1&ul=z3kl&hd=z3tg"; delPer=0; PSINO=2; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; ab_sr=1.0.1_NjNiODA3MTZjNzE4ZjA2YjUyNWFhNGU1ODc2ZDQ0MTQ1YmE4ODUzYTE4YzJkYjkzMWVhNWFhMmJkNDFlZWMwN2Q4YjU2YWQyOTdmZmE4MjE1YjY2YzQ3YjIzODM2NGEwYTY2NjM1YmI3MjRjODYyNGQ1M2RhZjA4NzUzYjQ3NjVlNjM4ZGY5MzJkYTllOTEwNmYxMDFlYzBmNzViNzFiYTU3MzBjNDljYzYzYWZkZDZkM2E3OWM5ZWVkNDE4YzdmYjQwNTRjM2E4YWM5ZDQwZmVmNWQ3ZWYxZDM2OWRiMmY1ZjgwM2YxYzNhYTAzZDA4YmE4Yzc2MzIxM2U5ZDM4Mg==; smallFlowVersion=old; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1721619578; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1721619578; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1' ,
"Sec-Fetch-Dest" : "empty" ,
"Sec-Fetch-Mode" : "cors" ,
"Sec-Fetch-Site" : "same-origin" }
data = urllib. parse. urlencode( data) . encode( "utf-8" )
request = urllib. request. Request( url= url, data= data, headers= headers)
response = urllib. request. urlopen( request)
content = response. read( ) . decode( "utf-8" )
obj = json. loads( content)
print ( "转为json数据输出即可" , obj)
但是,我们其实只需要Cookie就够了,甚至有了它,UA都可以不用
5. ajax
1. get请求
进入豆瓣电影,点击排行榜,点击动作分类,就会出现动作类电影的榜单,而这些数据可见来源于https://movie.douban.com/j/chart/top_list?type=5&interval_id=100:90&action=&start=0&limit=20这个请求
同时可以发现,它的响应体是ajax数据,也就是json数据
json数据在pycharm中可以通过快捷键Ctrl + Alt + L 来快速进行排版,方便我们查看
'''导包(start)'''
import urllib. request
import urllib. parse
import json
'''导包(end)'''
url = "https://movie.douban.com/j/chart/top_list?type=5&interval_id=100:90&action=&start=0&limit=20"
headers = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0'
}
request = urllib. request. Request( url= url, headers= headers)
response = urllib. request. urlopen( request)
content = response. read( ) . decode( "utf-8" )
with open ( 'douban.json' , 'w' , encoding= 'utf-8' ) as fp:
fp. write( content)
2. 如何爬取多页数据
上面我们获取了第一页的数据,一共20部电影,接口为https://movie.douban.com/j/chart/top_list?type=5&interval_id=100:90&action=&start=0&limit=20
然后我们清空network,向下滑页面,让其获取第二页数据,也就是21开始。我们发现接口为https://movie.douban.com/j/chart/top_list?type=5&interval_id=100:90&action=&start=20&limit=20
除了最后的一个参数start不同以外,其余都是相同的。所以我们找到了规律,不同页的数据,只是最后两个参数以20为一页进行变化罢了
用一个for循环,url的start参数0开始,不断递增20即可
'''导包(start)'''
import urllib. request
import urllib. parse
import json
'''导包(end)'''
headers = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0'
}
def create_requestUrl_byPage ( page) :
base_url = "https://movie.douban.com/j/chart/top_list?type=5&interval_id=100:90&action=&"
data = {
"start" : page* 20 ,
"limit" : 20 ,
}
data = urllib. parse. urlencode( data)
url = base_url + data
return url
def get_content ( url) :
request = urllib. request. Request( url= url, headers= headers)
response = urllib. request. urlopen( request)
content = response. read( ) . decode( "utf-8" )
return content
def output_to_file ( content, page) :
with open ( "第" + str ( page) + '页数据.json' , 'w' , encoding= 'utf-8' ) as fp:
fp. write( content)
if __name__ == '__main__' :
startPage = 0
endPage = 10
for page in range ( startPage, endPage) :
url = create_requestUrl_byPage( page)
print ( url)
content = get_content( url)
output_to_file( content, page+ 1 )
第一页数据,可见爬取到的数据是正确的
第二页数据,也是正确的
最后一页数据
3. post请求
可以发现数据来源于一个Post接口http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname
我们查看请求头,会发现X-Requested-With:XMLHttpRequest
这个参数,表示这个是ajax请求
分析不同页的表单数据,可以发现,只是页码pageIndex不一样而已
和前面Post一样,只不过这里返回的是ajax
'''导包(start)'''
import urllib. request
import urllib. parse
import json
'''导包(end)'''
headers = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0'
}
def create_requestUrl_byPage ( 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' )
return [ base_url, data] ;
def get_content ( url, data) :
request = urllib. request. Request( url= url, data= data, headers= headers)
response = urllib. request. urlopen( request)
content = response. read( ) . decode( "utf-8" )
return content
def output_to_file ( content, page) :
with open ( "第" + str ( page) + '页数据.json' , 'w' , encoding= 'utf-8' ) as fp:
fp. write( content)
if __name__ == '__main__' :
startPage = 1
endPage = 10
for page in range ( startPage, endPage+ 1 ) :
list = create_requestUrl_byPage( page)
print ( list )
content = get_content( list [ 0 ] , list [ 1 ] )
output_to_file( content, page)
第一页数据对应 第7页数据 因为一共只有7页,所以后面几页是空
6. 异常URLError\HTTPError
HTTPError类是URLError类的子类 导入的包是urllib.error.HTTPError和urllib.error.URLError http错误:http错误是针对浏览器无法连接到服务器而增加出来的错误提示。引导并告诉浏览者该页是哪里出了问题 通过urllib发送请求的时候,有可能会发送失败,这个时候如果想让你的代码更加的健壮,可以通过try‐except进行捕获异常,异常有两类,URLError\HTTPError
假设访问CSDN上的一篇文章https://blog.csdn.net/grd_java/article/details/140174015,我故意往后面加几个666666,此时这个请求就是错误的,执行代码会直接报错
直接返回报错信息,用户体验很差,因此我们需要捕获异常返回合理的信息
try :
request = urllib. request. Request( url, headers= headers)
response = urllib. request. urlopen( request)
print ( response. read( ) . decode( "utf8" ) )
except urllib. error. HTTPError as e:
print ( "请检查访问地址,错误码:" , e. code)
假设访问百度,但是将域名写错了,此时就会报URL错误,而我们捕获HTTP错误是不行的,因为URLError是HTTPError的父类
捕获
'''导包(start)'''
import urllib. request
import urllib. error
'''导包(end)'''
url = "https://www.baidu.coms"
headers = { "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0" }
try :
request = urllib. request. Request( url, headers= headers)
response = urllib. request. urlopen( request)
print ( response. read( ) . decode( "utf8" ) )
except urllib. error. URLError as e:
print ( "URL地址出错:" , e. reason)
7. cookie登录
有些数据是必须登录后才能获取的,这种应该如何爬取呢?
我们先登录,然后进入个人主页,发现个人数据来源于https://weibo.com/ajax/user/popcard/get?id=5458187191
我们直接爬取会提示编码错误,但是我们个人主页确实是utf-8,这是常用的反爬手段,你没有登录,会自动跳转页面,例如跳转到登录页面,而这个页面的编码不是utf-8,一般是gb2312
此时将编码改为gb2312就会发现,爬取到的页面是验证页面
此时,我们选择将请求头里面的东西,放在headers中再做尝试,其实依然只需要Cookie而已
'''导包(start)'''
import urllib. request
import urllib. error
'''导包(end)'''
url = "https://weibo.com/ajax/user/popcard/get?id=你的id"
headers = {
'Referer' : 'https://weibo.com/u/5458187191' ,
'Cookie' : '你的cookie' ,
}
request = urllib. request. Request( url, headers= headers)
response = urllib. request. urlopen( request)
content = response. read( ) . decode( "utf-8" )
with open ( 'test.json' , 'w' , encoding= 'utf-8' ) as f:
f. write( content)
请求头中有一个参数’Referer’:‘https://weibo.com/u/5458187191’, 虽然这个案例不需要,但是有些网站是需要的,这个参数代表上一个页面 也就是有些网站,是需要判断你的referer是不是从上一个页面进来的,不是的话,也会对你反爬处理 这个参数一般用于做图片防盗链的,所以我们需要注意这个问题
8. handler处理器
urllib.request.urlopen(url)是不能定制请求头的 urllib.request.Request(url,headers,data)是可以定制请求头的 Handler:可以定制更高级的请求头,随着业务逻辑逐渐复杂,请求对象的定制是无法满足需求的,例如动态cookie和代理都无法使用我们上面学到的定制请求对象来处理
1. Handler处理器基本使用
'''导包(start)'''
import urllib. request
import urllib. error
'''导包(end)'''
url = "https://www.baidu.com"
headers = {
"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0"
}
request = urllib. request. Request( url, headers= headers)
handler = urllib. request. HTTPHandler( )
openner = urllib. request. build_opener( handler)
response = openner. open ( request)
result = response. read( ) . decode( 'utf-8' )
print ( result)
2. 代理
突破自身IP访问限制,访问国外站点 访问一些单位或团体内部资源
扩展:某大学FTP(前提是该代理地址在该资源的允许访问范围之内),使用教育网内地址段免费代理服务器,就可以用于对教育网开放的各类FTP下载上传,以及各类资料查询共享等服务
提高访问速度
扩展:通常代理服务器都设置一个较大的硬盘缓冲区,当有外界的信息通过时,同时也将其保存到缓冲区中,当其他用户再访问相同的信息时, 则直接由缓冲区中取出信息,传给用户,以提高访问速度。
隐藏真实IP
扩展:上网者也可以通过这种方法隐藏自己的IP,免受攻击。
创建Reuqest对象 创建ProxyHandler对象 用handler对象创建opener对象 使用opener.open函数发送请求
百度快代理,会给我们提供很多免费代理ip
我们已知一个代理ip为202.101.213.154,端口号为18014 代码中规定proxies字典时,其中一个代理的格式就是’http’: ‘202.101.213.154:18014’
可见使用免费代理访问成功,如果免费都不行,那就只能买一个了
代码和上面Handler基本使用的唯一区别就是HttpHandler()换成ProxyHandler(proxies= proxies),额外需要指定一个proxies字典
'''导包(start)'''
import urllib. request
import urllib. error
'''导包(end)'''
url = "https://www.baidu.com"
headers = {
"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0"
}
request = urllib. request. Request( url, headers= headers)
proxies = {
'http' : '202.101.213.154:18014' ,
}
handler = urllib. request. ProxyHandler( proxies= proxies)
openner = urllib. request. build_opener( handler)
response = openner. open ( request)
result = response. read( ) . decode( 'utf-8' )
print ( result)
先生成API链接 点击生成链接后将链接复制到浏览器执行
此时就会给你一个高密的代理ip和端口号
此时,你查询自己的ip时,就会变成代理ip
3. 代理池
就算有一个代理ip,如果你使用这个ip高频次访问一个网站,依然会被封掉 因此需要一个代理池,多个ip轮番访问,也就是用一堆高密的代理ip进行爬虫,而不是只用几个ip,很快就会被识别为爬虫
可见上图中,会在代理池中随机挑选ip
'''导包(start)'''
import random
'''导包(end)'''
proxies_pool = [
{ 'http' : '202.101.213.154:1801411111111' } ,
{ 'http' : '202.101.213.154:1801422222222' } ,
{ 'http' : '202.101.213.154:1801433333333' }
]
proxies = random. choice( proxies_pool)
proxies1 = random. choice( proxies_pool)
proxies2 = random. choice( proxies_pool)
print ( proxies)
print ( proxies1)
print ( proxies2)