一、添加User-Agent防止反爬
1.User-Agent的用处:模拟真实的浏览器发送请求,防止反爬。
2.添加请求头的两种方式
①添加headers的方法1:在urllib.request.Request(url,headers=XXX)中进行传参,代码如下:
url = "http://www.baidu.com/"
#添加请求头的信息
header = {
"User-Agent":"Mozilla/5.0(Linux;Android6.0;Nexus5Build/MRA58N)AppleWebKit / 537.36(KHTML, likeGecko)Chrome / 75.0.3770.100MobileSafari / 537.36"
}
#创建请求对象request;
# 添加headers的方法1:在urllib.request.Request中进行传参
request = urllib.request.Request(url,headers=header)
②添加headers的方法2:利用 request.add_header(“User-Agent”,“xxx”)动态的去添加headers
url = "http://www.baidu.com/"
#创建请求对象request;
request = urllib.request.Request(url)
#添加headers的方法2:动态的去添加headers
request.add_header("User-Agent","Mozilla/5.0(Linux;Android6.0;Nexus5Build/MRA58N)AppleWebKit / 537.36(KHTML, likeGecko)Chrome / 75.0.3770.100MobileSafari / 537.36")
3.打印请求头的信息
①方式1:request.headers
#获取请求头的信息(所有头的信息)
request_headers = request.headers
print(request_headers)
②方式2:request.get_header(“User-agent”)
#第二种方式打印headers的信息
#注意:"User-agent"首字母需要大写,其他字母都要小写
request_headers = request.get_header("User-agent")
print(request_headers)
4.打印响应头的信息:print(response.headers)
5.添加随机的User-Agent
①先添加一个列表,列表中包含多个User-Agent。
user_agent_list=[
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
"Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.9.168 Version/11.50",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
]
②创建变量random_user_agent ,随机选取User-Agent。
random_user_agent = random.choice(user-agent_list)
③使用request.add_header动态添加header数据。
request.add_header("User-Agent",random_user_agent)
二、使用IP代理防止反爬
1.IP代理
①免费的IP:时效性差,错误率高;
②付费的IP:花钱,也有失效不能用的。
2.IP分类
①透明的:对方知道我们真实的IP;
②匿名:对方不知道我们真实的IP,也不知道我们使用了代理;
③高匿:对方不知道我们真实的IP,也不知道我们使用了代理;
3.创建Handler,创建Openner
①背景
系统的urlopen(urllib.request.urlopen())并没有添加代理的功能(IP相同相关网站会反爬),所以我们要自定义这个功能。
② urlopen为什么可以请求数据?
通过urllib.request.urlopen()的底层代码,可以看到核心是因为:①有handler处理器。②有openner(openner是用来请求数据的)。
③创建最基础的Handler(HTTPHandler),创建Openner
③.1创建最基础的Handler(HTTPHandler)
#1.创建自己的处理器(以下内容出自urllib.request.urlopen()源码)
handler = urllib.request.HTTPHandler()
③.2创建Openner
#2.创建自己的openner
openner = urllib.request.build_opener(handler)
③.3用创建的Openner请求数据
#用自己创建的opernner调用open方法请求数据
response = openner.open(url)
#urlopen的底层代码中reruen的就是openner.open,代码如下:
return opener.open(url, data, timeout)
#所以用自己创建的opernner调用open方法请求数据与urlopen效果一致。
④创建带IP代理的Handler(ProxyHandler),创建Openner
④.1创建Handler
#创建handler处理器
proxy_handler = urllib.request.ProxyHandler(proxy)
其中proxy为添加的代理。
使用免费的IP,proxy写法如下:
proxy = {
#①官方写法
"http":"http://117.57.91.153:9999"
#②简写
# "http":"117.57.91.153:9999"
}
使用付费的IP,proxy写法如下:
proxy = {
#付费的写法:通常会给一个账号密码,用拼接字符串的方式
"http":"xiaoming":123@1133.....
}
④.2创建Openner
#创建openner
openner = urllib.request.build_opener(proxy_handler)
⑤随机添加IP代理的方法
⑤.1添加代理池
proxy_list = [
{"http":"117.0.91.153:9999"},
{"http": "27.152.25.117:9999"},
{"http":"183.164.239.8:9999"},
{"http": "114.235.84.120:9999"},
{"http":"120.83.98.27:9999"}
]
⑤.2可以使用random.choice的方式随机取IP,但如果想要每次都使用新的IP去访问,需要用到遍历
for proxy in proxy_list:
# 利用遍历出来的IP创建处理器
proxy_handler = urllib.request.ProxyHandler(proxy)
# 利用遍handler创建openner
openner_random = urllib.request.build_opener(proxy_handler)
⑤.3考虑有可能存在部分IP失效的情况,因此可使用if或者try,except的方式防止报错运行不下去:
try:
data = openner_random.open(url, timeout=1)
print("Success!")
except Exception as e:
print(e)
三、代码1——添加请求头的两种方式
import urllib.request
def load_baidu():
url = "http://www.baidu.com/"
#添加请求头的信息
header = {
"User-Agent":"Mozilla/5.0(Linux;Android6.0;Nexus5Build/MRA58N)AppleWebKit / 537.36(KHTML, likeGecko)Chrome / 75.0.3770.100MobileSafari / 537.36"
}
#创建请求对象request;
# 添加headers的方法1:在urllib.request.Request中进行传参
request = urllib.request.Request(url,headers=header)
#获取请求头信息
print(request.headers)
#添加headers的方法2:动态的去添加headers
#request = urllib.request.Request(url)
#request.add_header("User-Agent","Mozilla/5.0(Linux;Android6.0;Nexus5Build/MRA58N)AppleWebKit / 537.36(KHTML, likeGecko)Chrome / 75.0.3770.100MobileSafari / 537.36")
#print(request.headers)
#请求网络数据(不在此处添加请求头的信息,因为此方法系统没有提供参数)
response = urllib.request.urlopen(request)
data = response.read().decode("utf-8")
#获取到完整的url
final_url = request.get_full_url()
print(final_url)
#响应头
# print(response.headers)
#获取请求头的信息(所有头的信息)
#request_headers = request.headers
# print(request_headers)
#第二种方式打印headers的信息
#注意:"User-agent"首字母需要大写,其他字母都要小写
request_headers = request.get_header("User-agent")
# print(request_headers)
with open("request_headers.html",'w',encoding="utf-8") as aaa:
aaa.write(data)
load_baidu()
四、代码2——随机添加User-Agent
import urllib.request
import random
def load_baidu():
url = "http://www.baidu.com/"
user_agent_list=[
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
"Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.9.168 Version/11.50",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
]
#要求每次请求的user-agent都是不一样的
random_user_agent = random.choice(user_agent_list)
# 创建请求对象
request = urllib.request.Request(url)
#动态增加对应的请求头信息(user-agent)
request.add_header("User-Agent",random_user_agent)
# 请求头信息
print(request.get_header("User-agent"))
#请求数据
response = urllib.request.urlopen(request)#把请求对象传进去
load_baidu()
五、代码3——创建最基础的Handler(HTTPHandler),创建Openner进行数据请求
import urllib.request
def handler_openner():
#系统的urlopen(urllib.request.urlopen())并没有添加代理的功能(IP相同相关网站会反爬)所以我们要自定义这个功能
#安全 套接层 ssl 第三方的CA数字证书
#http80端口和https443
#urlopen为什么可以请求数据?核心是因为①有handler处理器。②有openner(openner是用来请求数据的)。
url = "http://www.baidu.com/"
#1.创建自己的处理器(以下内容出自urllib.request.urlopen()源码)
handler = urllib.request.HTTPHandler()
#2.创建自己的openner
openner = urllib.request.build_opener(handler)
#用自己创建的opernner调用open方法请求数据
response = openner.open(url)
print(response)
data = response.read().decode()
print(data)
with open("05-handler-openner.html",'w',encoding="utf-8") as f:
f.write(data)
handler_openner()
六、代码4——创建带IP代理的ProxyHandler(HTTPHandler),创建Openner进行数据请求
#handler:
# 系统的urlopen()不支持代理的添加,需要创建对应的handler
# 1.代理处理器:urllib.request.ProxyHandler(proxy)
# 2.创建对应的openner:urllib.request.build_opener()
# 3.拿着创建的openner请求数据:openner.open(url)
import urllib.request
def creat_proxy_handler():
url = "https://news.sina.cn/gn/2019-11-23/detail-iihnzahi2866139.d.html"
#添加代理
proxy = {
#免费的写法
# ① #"http":"http://117.57.91.153:9999" #官方写法
#② "http":"117.57.91.153:9999"#简写
#付费的写法
# "http":"xiaoming":123@1133..... 会给一个账号密码
}
#创建handler处理器
proxy_handler = urllib.request.ProxyHandler(proxy)
#创建openner
openner = urllib.request.build_opener(proxy_handler)
#拿着自己代理的IP去访问请求
data = openner.open(url).read()
print(data)
creat_proxy_handler()
七、代码5——创建IP代理池,遍历IP代理创建Handler和Openner
import urllib.request
def proxy_user():
url = "http://www.baidu.com"
proxy_list = [
{"http":"111.79.45.239:9999"},
{"http": "123.149.141.23:9999"},
{"http":"49.77.209.51:9999"},
{"http": "59.52.184.87:9999"},
{"http":"120.83.98.27:9999"}
]
for proxy in proxy_list:
# 利用遍历出来的IP创建处理器
proxy_handler = urllib.request.ProxyHandler(proxy)
# 利用遍handler创建openner
openner_random = urllib.request.build_opener(proxy_handler)
try:
data = openner_random.open(url, timeout=1)
print("Success!")
except Exception as e:
print(e)
proxy_user()