2020-04-04日爬虫练习
每日一个爬虫小练习,学习爬虫的记得关注哦!
学习编程就像学习骑自行车一样,对新手来说最重要的是持之以恒的练习。
在《汲取地下水》这一章节中看见的一句话:“别担心自己的才华或能力不足。持之以恒地练习,才华便会有所增长”,现在想来,真是如此。
分页爬取快代理国内免费高匿IP,并对IP进行清洗验证,将可用的IP储存到本地
学习爬虫,离不开高频访问(请求),现在很多网站为了抵御爬虫,设置防爬措施,对频繁访问的IP要求重新登录,或者或跳转至一个带有滑块验证的页面,要求用户登录或拖动滑块。目前对于反爬措施中IP限制,使用动态IP代理访问还是可行的。
IP代理有透明代理、匿名代理、混淆代理和高匿代理。这四种代理,主要是代理服务器端的配置不同,导致其向目标地址发送请求时,REMOTE_ADDR、HTTP_VIA、HTTP_X_FORWARDED_FOR三个变量不同。
一:透明代理(Transparent Proxy)
REMOTE_ADDR=Proxy IP
HTTP_VIA=Proxy IP
HTTP_X_FORWARDED_FOR=Your IP
透明代理虽然可以直接”隐藏”你的IP,但是还是可以从HTTP_X_FORWARDED_FOR来查到你是谁。
二:匿名代理(Anonymous Proxy)
REMOTE_ADDR=Proxy IP
HTTP_VIA=Proxy IP
HTTP_X_FORWARDED_FOR=Proxy IP
匿名代理比透明代理进步一点:别人只能知道你用了代理,无法知道你是谁。
三:混淆代理(Distorting Proxies)
REMOTE_ADDR=Proxy IP
HTTP_VIA=Proxy IP
HTTP_X_FORWARDED_FOR=Random IP address
与匿名代理相同,如果使用了混淆代理,别人还是能知道你在用代理,但是会得到一个假的IP地址,伪装的更逼真
四:高匿代理(High Anonymity Proxy)
REMOTE_ADDR=Proxy IP
HTTP_VIA=not determined
HTTP_X_FORWARDED_FOR=not determined
使用高匿代理,能让别人根本无法发现你是在用代理,所以是最好的选择。
1.requests
2.BeautifulSoup
3.threading.Thread # 多线程
1.由于快代理的HTTP 是大写,直接进行 requests请求的时候, requests请求可以成功,但是请求使用的将会是你真实的ip地址 ,所以得进行大小写转换。
2. 如果爬取到的代理IP协议是https,在访问http网站时,requests请求可以成功,但是请求使用的将会是你真实的ip地址
3. 一开始使用http://icanhazip.com/网站进行验证,如果正常ip,它返回值的text,将会是你请求IP,但是它对80,8080等一些特殊端口不友好,无法做到正确验证,而且响应速度慢,特别影响效率。
4. 使用https://www.baidu.com/进行验证有两个好处,
----百度支持http和https,所以两个协议都能使用代理IP进行正常访问
----百度请求和响应速度特别快,如果状态码为200,那就说明代理ip有效,能起到快速清洗效果
ps:这是我爬虫实战过程中遇到的问题,觉得有帮助的给个赞吧!
'''
爬取快代理IP,建设自己的爬虫代理池
version:01
author:金鞍少年
date:2020-04-04
'''
import requests
from bs4 import BeautifulSoup
import time
from threading import Thread
class Douban:
def __init__(self):
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36',
'Referer': 'https://www.kuaidaili.com/free/'
}
# 获取分页html
def get_page_html(self, url):
try:
result = requests.get(url=url, headers=self.headers)
result.raise_for_status() # 主动抛出一个异常
html = BeautifulSoup(result.text, 'lxml')
return html
except:
print('链接失败!')
# 获取免费ip 信息
def get_proxy(self, html):
proxies = [] # 代理池
trs = html.find('table', class_='table table-bordered table-striped').find('tbody').find_all('tr')
for tr in trs:
tcp = list(tr.stripped_strings)[3].lower()
ip = list(tr.stripped_strings)[0]
port = list(tr.stripped_strings)[1]
proxies.append((tcp, ip+":"+port)) # 拼接IP地址,端口号
return proxies
# 开启多线程任务
def test_proxies(self, proxies):
proxies = proxies
for proxy in proxies:
test = Thread(target=self.thread_test_proxy, args=(proxy[0], proxy[1],))
test.start()
# 开启线程验证ip模式
def thread_test_proxy(self, tcp, address):
try:
print('待验证ip:%s' % address)
# 因为TCP分http和https,所以分开传入做精准验证
result = requests.get('https://www.baidu.com/', headers=self.headers, proxies={tcp: address}, timeout=3) # timeout 超时时间
if result.status_code == 200:
self.save_proxys((tcp, address)) # 写入文件
else:
pass
except Exception:
pass
# 保存IP到本地
def save_proxys(self, proxy):
with open("./res/快代理免费高匿IP.text", 'a+') as f:
print('有效IP:【{}:{}】'.format(proxy[0], proxy[1]))
f.write('{}:{}'.format(proxy[0], proxy[1]) + '\n')
# 逻辑功能
def func(self, base_url, page):
for i in range(1, page): # 快代理分页
try:
time.sleep(1)
url = base_url.format(i)
proxies = self.get_proxy(self.get_page_html(url))
self.test_proxies(proxies)
except Exception as e:
print('错误类型:%s' % e)
continue
if __name__ == '__main__':
obj = Douban()
obj.func('https://www.kuaidaili.com/free/inha/{}/', 2) # rul 和爬取分页数
print('爬取完毕,IP录入成功!')