requests加代理
高匿API代理
此處使用的小象代理:1元100個,便宜,可以購買嘗試加下代理
存活期1到2分鐘
import time
import requests
from lxml import etree
response = requests.get('https://api.xiaoxiangdaili.com/ip/get?appKey=1128886144755716096&appSecret=2ICgJR7q&cnt=&wt=json&method=https&city=&province=').json()
for ip in response['data']:
proxy = f'http://{ip["ip"]}:{ip["port"]}'
print(proxy)
proxies = {
'http': proxy,
'https': proxy
}
# 加代理
# requests是proxies: {
# 'http': proxy,
# 'https': proxy
# }
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0'
}
source = requests.get('https://tool.lu/ip/', proxies=proxies, headers=headers).content.decode('utf-8')
# source = requests.get('https://tool.lu/ip/', headers=headers).content.decode('utf-8')
IP = etree.HTML(source).xpath("//form[@id='main_form']/p[1]/text()")
print(f"IP: {IP}")
注意:
proxies = {
'http': proxy,
'https': proxy
}
這個指的是代理服務商提供的代理伺服器支援什麼請求,兩個都加比較保險。
如果代理伺服器支援http,但你傳送https請求,代理伺服器不會對你的請求進行轉發,但是會消耗你的代理IP
隧道代理(短效版)
此處用的小象代理,1元1小時,便宜,可以嘗試加下代理
介紹:
隧道代理,一分鐘自動更換IP,不需要人為搭建代理IP池去加代理IP。
隧道代理有併發請求限制,預設每秒允許 5 個請求。
也可以手動切換代理IP(但切換間隔最低10秒):可以爬取網站報錯時嘗試手動切換IP。
但一般一分鐘自動切換已經很快了
弊端:
- 有的網站跳轉使它的代理IP加不上,但代理服務商提供的介面文件提供瞭解決方案
from lxml import etree
import requests
target_url = "https://tool.lu/ip/"
proxy_host = 'http-short.xiaoxiangdaili.com'
proxy_port = 10010
proxy_username = '1128907524343746560'
proxy_pwd = 'wZ3WMRtm'
proxyMeta = "http://%(user)s:%(pass)s@%(host)s:%(port)s" % {
"host": proxy_host,
"port": proxy_port,
"user": proxy_username,
"pass": proxy_pwd,
}
proxies = {
'http': proxyMeta,
'https': proxyMeta,
}
try:
# 設定手動切換IP
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0',
'Proxy-Switch-Ip': 'true'
}
source = requests.get(url=target_url, proxies=proxies, headers=headers).content.decode('utf-8')
IP = etree.HTML(source).xpath("//form[@id='main_form']/p[1]/text()")
print(f"IP: {IP}")
# IP: ['你的外網IP地址是:110.88.30.181']
# IP: ['你的外網IP地址是:49.74.88.38']
except Exception as e:
print(e)
隧道代理(動態轉發版)
隧道代理(動態轉發)無須自己提取代理IP,在使用者隧道內每一個請求透過一個隨機 IP 進行轉發,也就是ip存活時間不長。
弊端:
- IP存活時間不長
適用:
- 如果網站只是單純的封ip,而不以IP生成cookie,並用cookie進行登入抓取資料,可以用動態轉發版。
高匿API代理和隧道代理(短效版)
-
高匿API代理:可以取出來IP並看到,按量或按時購買
-
隧道代理:無法取出來IP並看到,隧道幫你切,只能按時購買
部署一個屬於自己的可以獲取代理IP的伺服器
- 使用者
- 呼叫普通伺服器的IP加埠號,獲取代理IP
- 普通伺服器
- 開設一個埠:用來接受撥號伺服器發來的IP
- 再開設一個埠:用來展示接受到的IP
- vps動態撥號伺服器
- 撥號上網,關閉網路,之後伺服器更換一次IP。
- 用miniproxy軟體佔用一個埠進行請求轉發。
- 伺服器有一套程式獲取自身IP地址,利用socket協議與普通伺服器進行通訊,向普通伺服器傳送我們的IP,每更換一次IP就傳送一次。
野生代理
市面上有野生代理,安全性低、穩定性差,不能用
來源:
- 駭客攻擊別人電腦,在別人電腦開設埠:設定轉發請求服務
- 如果別人電腦是個小伺服器,可能IP可用時間還長點
- 如果別人電腦是個私人電腦,關機你就沒法用了
- 代理伺服器未知,可能會獲取你的請求攜帶的隱私
刷票
刷票程式一般根據IP進行票數計算,可以根據代理IP進行刷票
簡易代理IP池
此處用到redis資料庫作為IP池
這個只是簡易代理IP池,理解其思想即可,後續我會釋出一個複雜代理IP池,是一個專案,可以用於實戰的。
思想:
add_IP:如果IP池少於5,則補充,補充的IP初始分數為0
get_IP:取出一個代理IP,進行訪問,訪問失敗,則分數加1,若分數小於3則插回IP池,若分數大於等於3則捨棄
-
代理IP池的補充
import time import requests import redis # 建立redis連線 r = redis.Redis(host='127.0.0.1', port=6379, db=4, decode_responses=True) # decode_responses=True: redis中儲存二進位制資料, True表示取出資料自動進行解碼 while True: if r.llen("my_proxy") < 5: response = requests.get( 'https://api.xiaoxiangdaili.com/ip/get?appKey=1128886144755716096&appSecret=2ICgJR7q&cnt=5&wt=json&method=https&city=&province=').json() for ip in response['data']: proxy = f'{ip["ip"]}:{ip["port"]}|0' r.lpush('my_proxy', proxy) else: print("代理IP池已經滿了") time.sleep(5)
-
代理IP池的彈出使用
import time import requests from lxml import etree import redis # 建立redis連線 r = redis.Redis(host='127.0.0.1', port=6379, db=4, decode_responses=True) while True: try: # 取出代理IP rr = r.rpop('my_proxy').split('|') ip = rr[0] score = int(rr[1]) # 新增代理IP proxy = f'http://{ip}' proxies = { 'http': proxy, 'https': proxy } print(f"代理IP: {proxy}") # 加代理 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0' } source = requests.get('https://tool.lu/ip/', proxies=proxies, headers=headers) # source = requests.get('https://tool.lu/ip/', headers=headers).content.decode('utf-8') except Exception as e: print(e) if score < 3: score += 1 print(f'請求{ip}出錯,分數為:{score}') r.lpush('my_proxy', f'{ip}|{score}') else: print(f'捨棄{ip}') continue IP = etree.HTML(source.content.decode('utf-8')).xpath("//form[@id='main_form']/p[1]/text()") print(f"IP: {IP}") print(f"狀態碼:{source.status_code}") if source.status_code in (200, 302): r.lpush('my_proxy', f'{ip}|0') else: if score < 3: score += 1 print(f'請求{ip}出錯,分數為:{score}') r.lpush('my_proxy', f'{ip}|{score}') else: print(f'捨棄{ip}')