搭建自己的ip代理池(python实现

# -*- coding:utf-8 -*-
import urllib2
import random
import lxml
from bs4 import BeautifulSoup
import time
import requests
from fake_useragent import UserAgent
from threading import *
import threading
import sys

screenLock = Semaphore(value=1)
# 信号量设置成 1
'''
2019/9/2
查看urllib2官方文档 BeautifulSoup 官方文档 lxml官方文档 重修爬虫基础知识
在使用 beautifulsoup的时候 推荐使用lxml作为解析器,因为效率更高,另外还有htmlparser python内置标准库
Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种: 
    Tag , NavigableString , BeautifulSoup , Comment .
    
    
1.代理IP的获取/补充渠道,定期把获取到的代理ip加入到代理池中(这里可以考虑python跟数据库的交互
2.代理ip的验证机制,定期验证代理池中ip的有效性,并删除掉所有失效的ip
3.一个web服务,用以提供获取一个随机代理的api
#4.squid3的维持脚本,它定期获取代理池中的可用ip,更新squid中的可转发代理列表
#5.一个调度器,程序的入口,用来协调各组件的运行
'''


def check_IP(ip, http_type):
    '''
    在python中,requests使用代理要比urllib好用太多,urllib还是有些交互性差。
    如果需要使用代理,你可以通过为任意请求方法提供 proxies 参数来配置单个请求:
    你也可以通过环境变量 HTTP_PROXY 和 HTTPS_PROXY 来配置代理。
    若你的代理需要使用HTTP Basic Auth,可以使用 http://user:password@host/ 语法:
    要为某个特定的连接方式或者主机设置代理,使用 scheme://hostname 作为 key, 它会针对指定的主机和连接方式进行匹配。
    在这里我们使用proxies参数来配置单个请求,检测ip地址的存活情况
    '''
    proxy_ip = {http_type: ip}
    headers = headers_pool()
    result = requests.get("http://www.baidu.com", headers=headers, proxies=proxy_ip)
    if result.status_code == 200:
        return True
    else:
        return False

def output(ip,port,web_type):
    screenLock.acquire()
    if (check_IP(str(ip + ":" + port), web_type)):
        sys.stdout.write(str(web_type) + "://" + str(ip) + ":" + str(port) + "   True\n")
    else:
        sys.stdout.write(str(web_type) + "://" + str(ip) + ":" + str(port) + "   False\n")
    screenLock.release()

def xici_catch_ip(rep):
    '''
    Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.
    它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.
    Beautiful Soup会帮你节省数小时甚至数天的工作时间.
    '''
    soup = BeautifulSoup(rep.read(), 'lxml')
    tr_list = soup.find_all('tr')[1:]
    '''
    最简单的过滤器是字符串.在搜索方法中传入一个字符串参数,Beautiful Soup会查找与字符串完整匹配的内容
    在这里我们从第二个 <tr> 的地方开始搜索,具体原因看西刺代理网站的源代码就可以知道
    
    如果传入正则表达式作为参数,Beautiful Soup会通过正则表达式的 match() 来匹配内容
    '''
    for tr in tr_list:
        td_list = tr.find_all('td')
        output(td_list[1].text,td_list[2].text,td_list[5].text)

    # 在西刺代理的每一页上有100个代理ip地址

def kuaidaili_catch_ip(rep):
    soup=BeautifulSoup(rep.read(),'lxml')
    tr_list=soup.find_all('tr')[1:]
    for tr in tr_list:
        td_list=tr.find_all('td')
        output(td_list[0].text,td_list[1].text,td_list[3].text)

def headers_pool():
    '''
    使用fake_useragent来每次随机生成不同的useragent 避免在爬取代理ip的时候被代理网站屏蔽
    '''
    ua = UserAgent()
    headers = {'User-Agent': ua.random}
    return headers

def log():
    return '''
    

  __                   __    __________                             
_/  |_  ____   _______/  |_  \______   \_______  _______  ______.__.
\   __\/ __ \ /  ___/\   __\  |     ___/\_  __ \/  _ \  \/  <   |  |
 |  | \  ___/ \___ \  |  |    |    |     |  | \(  <_> >    < \___  |
 |__|  \___  >____  > |__|____|____|     |__|   \____/__/\_ \/ ____|
           \/     \/    /_____/                            \/\/     


    '''
def check_url(url):
    headers = headers_pool()
    req = urllib2.Request(url, headers=headers)
    try:
        return urllib2.urlopen(req)
    except urllib2.URLError:
        pass

def xici_url():
    url = "https://www.xicidaili.com/nn/"
    for i in range(1, 10):
        test_url = url + str(i)
        rep=check_url(test_url)
        if rep!=None:
            t = threading.Thread(target=xici_catch_ip, args=(rep,))
            t.start()
        # 带参数的用args传元组类型(参数最后多加一个逗号“,”要不然会报错) 血的教训

def kuaidaili_url():
    url2 = "https://www.kuaidaili.com/free/inha/"
    for i in range(1, 10):
        test_url = url2 + str(i)
        rep=check_url(test_url)
        if rep!=None:
            t = threading.Thread(target=kuaidaili_catch_ip, args=(rep,))
            t.start()

def main():
    print log()
    xici_url()
    kuaidaili_url()

    '''
    发起请求的时候,使用urllib2里面的Requests方法 带url 和 headers 
    使用urllib2里面的urlopen方法的时候不需要带headers
    我们客户端先对服务器端发起请求 带上自己的headers信息 服务器返回request 对应的 请求响应 response 
    '''

if __name__ == "__main__":
    main()

后期编写添加API接口以及代理池与数据库的交互

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值