点击上方“程序人生”,选择“置顶公众号”
第一时间关注程序猿(媛)身边的故事
图片源自unsplash
作者
fightjiang
如需转载,请联系原作者授权。
是不是有很多小伙伴都有这种经历,爬网站的时候,由于某些原因,IP 突然就被封了,怎么办勒?是的,今天我们要做的就是爬取网上的免费代理 IP ,再也不用担心自己的 IP 被封啦,爬取的过程很流畅。
确定目标URL:
我们要爬取的是快代理的免费代理 IP ,下面是我们的目标网站。
https://www.kuaidaili.com
代码解析:
这是向网页发出请求的函数,老套路了,相信大家心里肯定很清楚了。
# 向网页请求数据,老套路了
def get_one_page(url):
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'
}
reponse = requests.get(url,headers = headers)
if reponse.status_code == 200:
return reponse.text
return None
except RequestException:
return None
获取网站相应的 IP 以及端口,并将数据保存在本地,也是老套路了,如果有不怎么熟悉的小伙伴,可以看看前面的文章哟。
def get_one_parse(url):
with open('/Users/lec/Desktop/456.txt', 'a+') as f: # 保存在相应的文件里
print(url) # 看爬取到第几页来了
html = get_one_page(url)
html = etree.HTML(html)# 从获得的html页面中分析提取出所需要的数据
IP = html.xpath('.//*[@id="list"]/table/tbody//td[1]/text()') # 解析到相应的位置,用我上次教大家的方法,很方便的
poots = html.xpath('.//*[@id="list"]/table/tbody//td[2]/text()')# 这是 端口位置
for (ip,poot) in zip(IP,poots): # 保存
ip = ip +':' + poot
print("测试:{}".format(ip))
f.write(ip + '\n')
#validate(ip)
这是主函数,用一个 for 循环,模拟网站翻页的处理,并在每一次爬完一页之后,休息一秒。
def main():
url = 'https://www.kuaidaili.com/free/intr/{}/' # 这是网站的 url
for i in range(1,20): # 爬取二十页
time.sleep(1) # 休息 1 秒
get_one_parse(url.format(i))
你以为这篇文章是在和你讲老套路吗?不存在的,我在爬取 IP 的同时,一开始有想边爬取,边进行 IP 是否有效的验证,结果是贼慢了,根本无法忍受的速度,于是我写了另外的一个脚本来专门进行 IP 是否有效的验证,上面的代码就只需要把 IP 保存到本地就可以了啦!
我们这里采用多线程并发的方法来进行 IP 是否有效的验证,速度还是挺快的,我这里设置了全局变量,为了大家阅读的方便,我一次性把代码全部贴出来了,基本上每行代码都有非常详细的解释的,这里是使用了 map 简捷实现 Python 程序并行化,想要深入学习的小伙伴请自行查资料,我这里就不再详细介绍了,上代码!
import requests
from multiprocessing.dummy import Pool as ThreadPool # 引入这个库来获得map函数的并发版本
#设置全局变量,来保存可用的 IP
alive_ip = []
def validate(ip):
IP = {'http':ip} #指定对应的 IP 进行访问网址
try:
r = requests.get('http://www.baidu.com', proxies=IP, timeout=3)# proxies 设定对应的代理 IP 进行访问, timeout 设定相应的时间之后停止等待响应
if r.status_code == 200:
print("成功:{}".format(ip))
alive_ip.append(ip) # 有效的 IP 则添加进去
except:
print("无效")
def save():
with open('/Users/lec/Desktop/ip.txt','a+') as f: # 将有效的 IP 写入文件中保存
for ip in alive_ip:
f.write(ip+'\n')
print(ip)
print("成功保存所有有效 ip ")
def main():
with open('/Users/lec/Desktop/456.txt','r') as f:
lines = f.readlines()
# 我们去掉lines每一项后面的\n\r之类的空格
# 生成一个新的列表!
ips = list(map(lambda x:x.strip(),[line for line in lines]))# strip() 方法用于移除字符串头尾指定的字符,默认就是空格或换行符。
pool = ThreadPool(20) # 多线程 设置并发数量!
pool.map(validate, ips) # 用 map 简捷实现 Python 程序并行化
save() # 保存能用的 IP
if __name__ == "__main__":
main()
成果展示:
这个脚本的执行速度还是不错的,同时我们也发现,爬取了 20 页的代理 IP ,能用的却少的可怜,如果自己手动一个一个的去验证,绝对自己先崩溃了,右边的是可用的 IP ,左边的是全部的 IP(未全部展示出来)。
- The End -
「若你有原创文章想与大家分享,欢迎投稿。」
加编辑微信ID,备注#投稿#:
程序 丨 druidlost
小七 丨 duoshangshuang
《PHP 7底层设计与源码实现》作者分享交流会
作者简介
滴滴顺风车运营营销研发团队技术负责人——陈雷老师即将分享新书《PHP 7底层设计与源码实现》中的一些知识点。
进群方式
扫下图二维码或添加小助手微信ID:Balance_Do,回复「PHP7」。然后拉你进群。
进群后可以
1 听嘉宾浅谈内存管理,Zval和HashTable,有机会和嘉宾互动交流;
2 嘉宾分享结束后,从群内活跃互动者中抽取5名幸运用户,免费得此书。
分享时间
7月6日(本周五)12点(分享开始前一小时起停止拉人入群。想听作者关于PHP7源码内容分享的用户请留意在此时间前进群)
开奖时间
7月6日当天作者分享结束后,群内抽奖。
更多精彩内容