python爬虫精选09集(IP代理、requests.post参数、破解有道词典)
时间:04-24来源:作者:点击数:
一.IP代理
1.常见代理平台
- 西刺代理、快代理、芝麻代理、全网代理、阿布云代理、代理精灵
2.作用及理解
- 隐藏自身真实IP,避免被封
- 请求时,先将请求发给代理服务器,代理服务器请求目标服务器,然后目标服务器将数据传给代理服务器,代理服务器再将数据给爬虫。
- 代理服务器是经常变化的,使用代理服务器时传一个参数:proxy,是一个字典的形式。
3.代理IP种类
- 普通代理
Web端知道有人通过此代理IP访问,但不知用户真实IP
- 透明代理
Web能看到用户真实IP,也能看到代理IP
- 高匿代理
Web端只能看到代理IP
4.实现方法
4.1普通代理思路
【1】获取代理IP网站
西刺代理、快代理、全网代理、代理精灵、阿布云、芝麻代理... ...
【2】参数类型
proxies = { '协议':'协议://IP:端口号' }
proxies = {
'http':'http://IP:端口号',
'https':'https://IP:端口号',
}
4.2普通代理
# 使用免费普通代理IP访问测试网站: http://httpbin.org/get
import requests
url = 'http://httpbin.org/get'
headers = {'User-Agent':'Mozilla/5.0'}
# 定义代理,在代理IP网站中查找免费代理IP
proxies = {
'http':'http://112.85.164.220:9999',
'https':'https://112.85.164.220:9999'
}
html = requests.get(url,proxies=proxies,headers=headers,timeout=5).text
print(html)
4.3私密代理+独享代理
【1】语法结构
proxies = { '协议':'协议://用户名:密码@IP:端口号' }
【2】示例
proxies = {
'http':'http://用户名:密码@IP:端口号',
'https':'https://用户名:密码@IP:端口号',
}
4.4私密代理+独享代理 - 示例代码
import requests
url = 'http://httpbin.org/get'
proxies = {
'http': 'http://309435365:szayclhp@106.75.71.140:16816',
'https':'https://309435365:szayclhp@106.75.71.140:16816',
}
headers = {
'User-Agent' : 'Mozilla/5.0',
}
html = requests.get(url,proxies=proxies,headers=headers,timeout=5).text
print(html)
4.5建立自己的代理IP池 - 开放代理 | 私密代理
"""
收费代理:
建立开放代理的代理IP池
思路:
1、获取到开放代理
2、依次对每个代理IP进行测试,能用的保存到文件中
"""
import requests
class ProxyPool:
def __init__(self):
self.url = '代理网站的API链接'
self.headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36'}
# 打开文件,用来存放可用的代理IP
self.f = open('proxy.txt', 'w')
def get_html(self):
html = requests.get(url=self.url, headers=self.headers).text
proxy_list = html.split('\r\n')
for proxy in proxy_list:
# 依次测试每个代理IP是否可用
if self.check_proxy(proxy):
self.f.write(proxy + '\n')
def check_proxy(self, proxy):
"""测试1个代理IP是否可用,可用返回True,否则返回False"""
test_url = 'http://httpbin.org/get'
proxies = {
'http' : 'http://{}'.format(proxy),
'https': 'https://{}'.format(proxy)
}
try:
res = requests.get(url=test_url, proxies=proxies, headers=self.headers, timeout=2)
if res.status_code == 200:
print(proxy,'\033[31m可用\033[0m')
return True
else:
print(proxy,'无效')
return False
except:
print(proxy,'无效')
return False
def run(self):
self.get_html()
# 关闭文件
self.f.close()
if __name__ == '__main__':
spider = ProxyPool()
spider.run()
- 实际效果
二.requests.post()参数
1.适用场景
- Post类型请求的网站
- 通过浏览器F12或者Fiddle抓包查看后台请求数据
2.参数类型
- response = requests.post(url,data=data,headers=headers)
- data :post数据(Form表单数据-字典格式)
3.post请求方式特点
- GET请求 : 参数在URL地址中有显示
- POST请求: Form表单提交数据
4.get与post区别
三.有道翻译破解
1.目标
破解有道翻译接口,抓取翻译结果
# 结果展示
请输入要翻译的词语: code
翻译结果: 代码
**************************
请输入要翻译的词语: 警告
翻译结果: warm
2.实现步骤
1、浏览器F12开启网络抓包,Network-All,页面翻译单词后找Form表单数据
2、在页面中多翻译几个单词,观察Form表单数据变化(有数据是加密字符串)
3、刷新有道翻译页面,抓取并分析JS代码(本地JS加密)
4、找到JS加密算法,用Python按同样方式加密生成加密数据
5、将Form表单数据处理为字典,通过requests.post()的data参数发送
3.具体实现
i: 喵喵叫
from: AUTO
to: AUTO
smartresult: dict
client: fanyideskweb
salt: 15614112641250
sign: 94008208919faa19bd531acde36aac5d
ts: 1561411264125
bv: f4d62a2579ebb44874d7ef93ba47e822
doctype: json
version: 2.1
keyfrom: fanyi.web
action: FY_BY_REALTlME
- 2、在页面中多翻译几个单词,观察Form表单数据变化
salt: 15614112641250
sign: 94008208919faa19bd531acde36aac5d
ts: 1561411264125
bv: f4d62a2579ebb44874d7ef93ba47e822
# 但是bv的值不变
- 3、一般为本地js文件加密,刷新页面,找到js文件并分析JS代码
【方法1】 : Network - JS选项 - 搜索关键词salt
【方法2】 : 控制台右上角 - Search - 搜索salt - 查看文件 - 格式化输出
【结果】 : 最终找到相关JS文件 : fanyi.min.js
- 4、打开JS文件,分析加密算法,用Python实现
【ts】经过分析为13位的时间戳,字符串类型
js代码实现) "" + (new Date).getTime()
python实现) str(int(time.time()*1000))
【salt】
js代码实现) ts + parseInt(10 * Math.random(), 10);
python实现) ts + str(random.randint(0,9))
【sign】('设置断点调试,来查看 e 的值,发现 e 为要翻译的单词')
js代码实现) n.md5("fanyideskweb" + e + salt + "n%A-rKaT5fb[Gy?;N5@Tj")
python实现)
from hashlib import md5
string = "fanyideskweb" + e + salt + "n%A-rKaT5fb[Gy?;N5@Tj"
s = md5()
s.update(string.encode())
sign = s.hexdigest()
- 5、pycharm中正则处理headers和formdata
【1】pycharm进入方法 :Ctrl + r ,选中 Regex
【2】处理headers和formdata
(.*): (.*)
"$1": "$2",
【3】点击 Replace All
import requests
import time
import random
from hashlib import md5
class YdSpider(object):
def __init__(self):
# url一定为F12抓到的 headers -> General -> Request URL
self.url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
self.headers = {
# 检查频率最高 - 3个
"Cookie": "OUTFOX_SEARCH_USER_ID=970246104@10.169.0.83; OUTFOX_SEARCH_USER_ID_NCOO=570559528.1224236; _ntes_nnid=96bc13a2f5ce64962adfd6a278467214,1551873108952; JSESSIONID=aaae9i7plXPlKaJH_gkYw; td_cookie=18446744072941336803; SESSION_FROM_COOKIE=unknown; ___rl__test__cookies=1565689460872",
"Referer": "http://fanyi.youdao.com/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36",
}
# 获取salt,sign,ts
def get_salt_sign_ts(self,word):
# ts
ts = str(int(time.time()*1000))
# salt
salt = ts + str(random.randint(0,9))
# sign
string = "fanyideskweb" + word + salt + "n%A-rKaT5fb[Gy?;N5@Tj"
s = md5()
s.update(string.encode())
sign = s.hexdigest()
return salt,sign,ts
# 主函数
def attack_yd(self,word):
# 1. 先拿到salt,sign,ts
salt,sign,ts = self.get_salt_sign_ts(word)
# 2. 定义form表单数据为字典: data={}
# 检查了salt sign
data = {
"i": word,
"from": "AUTO",
"to": "AUTO",
"smartresult": "dict",
"client": "fanyideskweb",
"salt": salt,
"sign": sign,
"ts": ts,
"bv": "7e3150ecbdf9de52dc355751b074cf60",
"doctype": "json",
"version": "2.1",
"keyfrom": "fanyi.web",
"action": "FY_BY_REALTlME",
}
# 3. 直接发请求:requests.post(url,data=data,headers=xxx)
html = requests.post(
url=self.url,
data=data,
headers=self.headers
).json()
# res.json() 将json格式的字符串转为python数据类型
result = html['translateResult'][0][0]['tgt']
print(result)
# 主函数
def run(self):
# 输入翻译单词
word = input('请输入要翻译的单词:')
self.attack_yd(word)
if __name__ == '__main__':
spider = YdSpider()
spider.run()