精华内容
下载资源
问答
  • 爬虫代理

    万次阅读 2018-08-19 17:21:44
    花了几天时间写了一个比较完整的爬虫代理模块,基本上实现了一个比较完整的代理系统。 有如下几大模块: ip的获取模块 检验及删除更新 requests循环请求 ip的获取 ip来源:http://www.xicidaili.com/wt/ ...

    前言

    花了几天时间写了一个比较完整的爬虫代理模块,基本上实现了一个比较完整的代理系统。

    有如下几大模块:

    • ip的获取模块
    • 检验及删除更新
    • requests循环请求

    ip的获取

    ip来源:http://www.xicidaili.com/wt/
    通过遍历西刺代理中的四个页面获取ip,然后对ip有效性进行检验,将有效的ip写入文件。这里需要注意一下,西刺代理有效的ip一般都在前面,后面基本都是失效了的,我选择每个页面的前30条ip地址来检验,后面的直接舍弃。

    	#http://www.xicidaili.com/wt/
    	def get_goubanjia(self,url_target):
    		try:
    			#设置headers
    			headers = {'User-Agent':str(UserAgent().random)}
    			#发送requests请求
    			req = requests.get(url_target,headers=headers, timeout=5)
    			#校正网页编码
    			req.encoding = req.apparent_encoding
    			#对网页进行解析
    			soup = BeautifulSoup(req.text, 'lxml')
    			tr_list = soup.find_all('tr')
    
    			for each in range(1, 31):
    				print('已经筛选了{}条ip'.format(each))
    				print("获取地址")
    				#获取地址
    				td = tr_list[each].find_all('td')
    				a = td[1].get_text()
    				print("获取端口")
    				#获取端口
    				b = td[2].get_text()
    				#将有效的ip写入文件
    				proxy = 'http://' + a+':'+b
    				#检验ip是否有效,将有效的ip写入文件当中
    				if self.verifyIP(proxy):
    					f = open('ip.txt','a+',encoding='utf-8')
    					f.write(proxy+'\n')
    					f.close()
    				#输出爬取到的信息
    				print(proxy)
    		except Exception as e:
    			print(str(e))
    			print('{}:网站页面发生变动,请及时更新'.format(url_target))
    

    ip的检验

    通过传入的proxy(‘http://123.123.123’),利用需要爬取的网站作为目标网站,发送requests请求来实现ip有效性的检验。
    在检验ip有效性的过程中,我发现了这样一个有趣的现象,同一批ip对不同网站的访问速度不同(排除了网站本身的访问速度原因)。打个比方,有A、B两个网站他们的服务器配置是一样的,但是a、b、c、d四个ip从发送请求到相应这中间的时间却是不一样的。
    所以,建议检验ip有效性时采用目标网站比较合适

    	#验证ip,返回True/False值
    	def verifyIP(self,proxy):
    		print('开始判断{}的有效性'.format(proxy))
    		try:
    			#设置ip
    			proxies = {'{}'.format(self.ip_stype):proxy}
    			#设置headers
    			headers = {'User-Agent':str(UserAgent().random)}
    			#发生requests请求
    			req = requests.get(self.url, headers=headers, proxies=proxies, verify=False, timeout=(6,14))
    		except Exception as e:
    			print('{}代理ip无效'.format(proxies))
    			print('在检验过程中遇到的requests错误原因是:{}'.format(e))
    			return False
    		else:
    			print('{}代理ip有效'.format(proxies))
    			return True
    		finally:
    			print('{}代理ip有效性判断完成'.format(proxies))
    

    删除ip

    删除ip这块相对而言简单一些,读取文件–>删除旧文件–>删除ip列表中的失效ip–>将ip列表写入文件。

    	#删除proxy
    	def deleteProxy(self,proxy):
    		print('删除无效proxy:{}'.format(proxy))
    		f = open('ip.txt', 'r', encoding='utf-8')
    		proxy_list = f.readlines()
    		f.close()
    		#删除列表中的换行符号
    		proxy_list = [proxy.replace('\n','') for proxy in proxy_list]
    		#删除原文件
    		os.remove('ip.txt')
    		#删除指定的proxy
    		proxy_list.remove(proxy)
    		#当文件为空时,重新下载文件
    		if len(proxy_list)==0:
    			print('现在列表为空,我们将重新获取ip')
    			#调用父类下载新的ip文件
    			super().getIpFile()
    		#将信息重新写入文件
    		f = open('ip.txt', 'a+', encoding='utf-8')
    		for each in proxy_list:
    			f.write(each+'\n')
    		f.close()
    

    ip文件的自动更新机制

    简单点来说就是在删除失效ip后检测文件是否为空,为空时,再次从互联网上下载一批新的ip

    	#删除指定的proxy
    	proxy_list.remove(proxy)
    	#当文件为空时,重新下载文件
    	if len(proxy_list)==0:
    		print('现在列表为空,我们将重新获取ip')
    		#调用父类下载新的ip文件
    		super().getIpFile()
    

    requests循环请求

    利用while构造一个死循环,只有在requests请求成功时,打破死循环的代码(flag=False)才会被执行,当然每一次循环都会采用新的IP地址以及headers

    flag=True
    while (flag!=False):
    	try:
    		try:
    			#设置代理ip
    			proxy = self.createRandomIp()
    			#设置proxies
    			proxies = {'{}'.format(self.ip_stype):proxy}
    			#设置代理headers
    			headers = {'User-Agent':str(UserAgent().random)}
    			req = requests.get(self.url, proxies=proxies, headers=headers, verify=False, timeout=(9,21))
    			flag=False
    		except Exception as e:
    			print('上一次请求失败,10秒后我们将进行下一次请求')
    			print("上一次requests请求失败的原因是{}".format(e))
    			print('上一次请求的代理ip为:{}'.format(proxy))
    			time.sleep(10)
    			#验证proxy的有效性,并对无效proxy进行处理
    			proxy = self.verifyProxy(proxy)
    			#设置proxies
    			proxies = {'{}'.format(self.ip_stype):proxy}
    			#设置代理headers
    			headers = {'User-Agent':str(UserAgent().random)}
    			req = requests.get(self.url, proxies=proxies, headers=headers, verify=False, timeout=(9,21))
    			flag=False
    	except:
    		pass
    

    备注

    考虑到短时间多次访问一个网站可能会被识别出来,故在第一次发送requests请求时是不检验ip的有效性,如果请求出错则10秒后会对该ip进行验证,中间间隔10秒是考虑到网络信号的影响。如果检验到ip失效则会将其从ip文件中删除。

    在删除失效ip后,会重新分配一个ip并对其有效性进行检验,无效则删除,重新分配ip直至分配的ip通过检验,采用的是递归算法。

    在requests请求这一块,也具有相同的思想,不断发送requests请求直至成功,采用while构造死循环。

    展开全文
  • Python爬虫代理池搭建

    万次阅读 多人点赞 2019-05-13 15:37:19
    一、为什么要搭建爬虫代理池 二、搭建思路 三、代码实现 ipproxy.py settings.py proxy_queue.py proxy_util.py proxy_crawlers.py run.py 四、代理测试 一、为什么要搭建爬虫代理池 在众多的网站防爬...

     

    目录

    一、为什么要搭建爬虫代理池

    二、搭建思路

    三、代码实现

    ipproxy.py

    settings.py

    proxy_util.py

    proxy_queue.py

    proxy_crawlers.py

    run.py

    四、代理测试


    一、为什么要搭建爬虫代理池

    在众多的网站防爬措施中,有一种是根据ip的访问频率进行限制,即在某一时间段内,当某个ip的访问次数达到一定的阀值时,该ip就会被拉黑、在一段时间内禁止访问。

    应对的方法有两种:

    1. 降低爬虫的爬取频率,避免IP被限制访问,缺点显而易见:会大大降低爬取的效率。

    2. 搭建一个IP代理池,使用不同的IP轮流进行爬取。

    二、搭建思路

    1、从代理网站(如:西刺代理、快代理、云代理、无忧代理)爬取代理IP;

    2、验证代理IP的可用性(使用代理IP去请求指定URL,根据响应验证代理IP是否生效);

    3、将可用的代理IP保存到数据库;

    常用代理网站:西刺代理 、云代理 、IP海 、无忧代理 、飞蚁代理 、快代理

    三、代码实现

    工程结构如下:

    ipproxy.py

    IPProxy代理类定义了要爬取的IP代理的字段信息和一些基础方法。

    # -*- coding: utf-8 -*-
    import re
    import time
    from settings import PROXY_URL_FORMATTER
    
    schema_pattern = re.compile(r'http|https$', re.I)
    ip_pattern = re.compile(r'^([0-9]{1,3}.){3}[0-9]{1,3}$', re.I)
    port_pattern = re.compile(r'^[0-9]{2,5}$', re.I)
    
    class IPProxy:
        '''
        {
            "schema": "http", # 代理的类型
            "ip": "127.0.0.1", # 代理的IP地址
            "port": "8050", # 代理的端口号
            "used_total": 11, # 代理的使用次数
            "success_times": 5, # 代理请求成功的次数
            "continuous_failed": 3, # 使用代理发送请求,连续失败的次数
            "created_time": "2018-05-02" # 代理的爬取时间
        }
        '''
    
        def __init__(self, schema, ip, port, used_total=0, success_times=0, continuous_failed=0,
                     created_time=None):
            """Initialize the proxy instance"""
            if schema == "" or schema is None:
                schema = "http"
            self.schema = schema.lower()
            self.ip = ip
            self.port = port
            self.used_total = used_total
            self.success_times = success_times
            self.continuous_failed = continuous_failed
            if created_time is None:
                created_time = time.strftime('%Y-%m-%d', time.localtime(time.time()))
            self.created_time = created_time
    
        def _get_url(self):
            ''' Return the proxy url'''
            return PROXY_URL_FORMATTER % {'schema': self.schema, 'ip': self.ip, 'port': self.port}
    
        def _check_format(self):
            ''' Return True if the proxy fields are well-formed,otherwise return False'''
            if self.schema is not None and self.ip is not None and self.port is not None:
                if schema_pattern.match(self.schema) and ip_pattern.match(self.ip) and port_pattern.match(self.port):
                    return True
            return False
    
        def _is_https(self):
            ''' Return True if the proxy is https,otherwise return False'''
            return self.schema == 'https'
    
        def _update(self, successed=False):
            ''' Update proxy based on the result of the request's response'''
            self.used_total = self.used_total + 1
            if successed:
                self.continuous_failed = 0
                self.success_times = self.success_times + 1
            else:
                print(self.continuous_failed)
                self.continuous_failed = self.continuous_failed + 1
    
    if __name__ == '__main__':
        proxy = IPProxy('HTTPS', '192.168.2.25', "8080")
        print(proxy._get_url())
        print(proxy._check_format())
        print(proxy._is_https())

    settings.py

    settings.py中汇聚了工程所需要的配置信息。

    # 指定Redis的主机名和端口
    REDIS_HOST = 'localhost'
    REDIS_PORT = 6379
    
    # 代理保存到Redis key 格式化字符串
    PROXIES_REDIS_FORMATTER = 'proxies::{}'
    # 已经存在的HTTP代理和HTTPS代理集合
    PROXIES_REDIS_EXISTED = 'proxies::existed'
    
    # 最多连续失败几次
    MAX_CONTINUOUS_TIMES = 3
    # 代理地址的格式化字符串
    PROXY_URL_FORMATTER = '%(schema)s://%(ip)s:%(port)s'
    
    USER_AGENT_LIST = [
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
        "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
        "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
        "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
        "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
    ]
    # 爬取到的代理保存前先检验是否可用,默认True
    PROXY_CHECK_BEFOREADD = True
    # 检验代理可用性的请求地址,支持多个
    PROXY_CHECK_URLS = {'https':['https://icanhazip.com'],'http':['http://icanhazip.com']}
    

    proxy_util.py

    proxy_util.py 中主要定义了一些实用方法,例如:proxy_to_dict(proxy)用来将IPProxy代理实例转换成字典;proxy_from_dict(d)用来将字典转换为IPProxy实例;request_page()用来发送请求;_is_proxy_available()用来校验代理IP是否可用。

    # -*- coding: utf-8 -*-
    import random
    import logging
    import requests
    from ipproxy import IPProxy
    from settings import USER_AGENT_LIST, PROXY_CHECK_URLS
    
    # Setting logger output format
    logging.basicConfig(level=logging.INFO,
                        format='[%(asctime)-15s] [%(levelname)8s] [%(name)10s ] - %(message)s (%(filename)s:%(lineno)s)',
                        datefmt='%Y-%m-%d %T'
                        )
    logger = logging.getLogger(__name__)
    
    
    def proxy_to_dict(proxy):
        d = {
            "schema": proxy.schema,
            "ip": proxy.ip,
            "port": proxy.port,
            "used_total": proxy.used_total,
            "success_times": proxy.success_times,
            "continuous_failed": proxy.continuous_failed,
            "created_time": proxy.created_time
        }
        return d
    
    
    def proxy_from_dict(d):
        return IPProxy(schema=d['schema'], ip=d['ip'], port=d['port'], used_total=d['used_total'],
                       success_times=d['success_times'], continuous_failed=d['continuous_failed'],
                       created_time=d['created_time'])
    
    
    # Truncate header and tailer blanks
    def strip(data):
        if data is not None:
            return data.strip()
        return data
    
    
    base_headers = {
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7'
    }
    
    
    def request_page(url, options={}, encoding='utf-8'):
        """send a request,get response"""
        headers = dict(base_headers, **options)
        if 'User-Agent' not in headers.keys():
            headers['User-Agent'] = random.choice(USER_AGENT_LIST)
    
        logger.info('正在抓取: ' + url)
        try:
            response = requests.get(url, headers=headers)
            if response.status_code == 200:
                logger.info('抓取成功: ' + url)
                return response.content.decode(encoding=encoding)
        except ConnectionError:
            logger.error('抓取失败' + url)
            return None
    
    def _is_proxy_available(proxy, options={}):
        """Check whether the Proxy is available or not"""
        headers = dict(base_headers, **options)
        if 'User-Agent' not in headers.keys():
            headers['User-Agent'] = random.choice(USER_AGENT_LIST)
        proxies = {proxy.schema: proxy._get_url()}
        check_urls = PROXY_CHECK_URLS[proxy.schema]
        for url in check_urls:
            try:
                response = requests.get(url=url, proxies=proxies, headers=headers, timeout=5)
            except BaseException:
                logger.info("< " + url + " > 验证代理 < " + proxy._get_url() + " > 结果: 不可用  ")
            else:
                if response.status_code == 200:
                    logger.info("< " + url + " > 验证代理 < " + proxy._get_url() + " > 结果: 可用  ")
                    return True
                else:
                    logger.info("< " + url + " > 验证代理 < " + proxy._get_url() + " > 结果: 不可用  ")
        return False
    
    
    if __name__ == '__main__':
        headers = dict(base_headers)
        if 'User-Agent' not in headers.keys():
            headers['User-Agent'] = random.choice(USER_AGENT_LIST)
        proxies = {"https": "https://163.125.255.154:9797"}
        response = requests.get("https://www.baidu.com", headers=headers, proxies=proxies, timeout=3)
        print(response.content)

    proxy_queue.py

    代理队列用来保存并对外提供 IP代理,不同的代理队列内代理IP的保存和提取策略可以不同。在这里, BaseQueue 是所有代理队列的基类,其中声明了所有代理队列都需要实现的保存代理IP、提取代理IP、查看代理IP数量等接口。示例的 FifoQueue 是一个先进先出队列,底层使用 Redis 列表实现,为了确保同一个代理IP只能被放入队列一次,这里使用了一个Redis proxies::existed 集合进行入队前重复校验。

    # -*- coding: utf-8 -*-
    from proxy_util import logger
    import json
    import redis
    from ipproxy import IPProxy
    from proxy_util import proxy_to_dict, proxy_from_dict, _is_proxy_available
    from settings import PROXIES_REDIS_EXISTED, PROXIES_REDIS_FORMATTER, MAX_CONTINUOUS_TIMES, PROXY_CHECK_BEFOREADD
    
    """
    Proxy Queue Base Class
    """
    class BaseQueue(object):
    
        def __init__(self, server):
            """Initialize the proxy queue instance
    
            Parameters
            ----------
            server : StrictRedis
                Redis client instance
            """
            self.server = server
    
        def _serialize_proxy(self, proxy):
            """Serialize proxy instance"""
            return proxy_to_dict(proxy)
    
        def _deserialize_proxy(self, serialized_proxy):
            """deserialize proxy instance"""
            return proxy_from_dict(eval(serialized_proxy))
    
        def __len__(self, schema='http'):
            """Return the length of the queue"""
            raise NotImplementedError
    
        def push(self, proxy, need_check):
            """Push a proxy"""
            raise NotImplementedError
    
        def pop(self, schema='http', timeout=0):
            """Pop a proxy"""
            raise NotImplementedError
    
    
    class FifoQueue(BaseQueue):
        """First in first out queue"""
    
        def __len__(self, schema='http'):
            """Return the length of the queue"""
            return self.server.llen(PROXIES_REDIS_FORMATTER.format(schema))
    
        def push(self, proxy, need_check=PROXY_CHECK_BEFOREADD):
            """Push a proxy"""
            if need_check and not _is_proxy_available(proxy):
                return
            elif proxy.continuous_failed < MAX_CONTINUOUS_TIMES and not self._is_existed(proxy):
                key = PROXIES_REDIS_FORMATTER.format(proxy.schema)
                self.server.rpush(key, json.dumps(self._serialize_proxy(proxy),ensure_ascii=False))
    
        def pop(self, schema='http', timeout=0):
            """Pop a proxy"""
            if timeout > 0:
                p = self.server.blpop(PROXIES_REDIS_FORMATTER.format(schema.lower()), timeout)
                if isinstance(p, tuple):
                    p = p[1]
            else:
                p = self.server.lpop(PROXIES_REDIS_FORMATTER.format(schema.lower()))
            if p:
                p = self._deserialize_proxy(p)
                self.server.srem(PROXIES_REDIS_EXISTED, p._get_url())
                return p
    
        def _is_existed(self, proxy):
            added = self.server.sadd(PROXIES_REDIS_EXISTED, proxy._get_url())
            return added == 0
    
    
    if __name__ == '__main__':
        r = redis.StrictRedis(host='localhost', port=6379)
        queue = FifoQueue(r)
        proxy = IPProxy('http', '218.66.253.144', '80')
        queue.push(proxy)
        proxy = queue.pop(schema='http')
        print(proxy._get_url())

    proxy_crawlers.py

    ProxyBaseCrawler 是所有代理爬虫的基类,其中只定义了一个 _start_crawl() 方法用来从搜集到的代理网站爬取代理IP。

    # -*- coding: utf-8 -*-
    from lxml import etree
    from ipproxy import IPProxy
    from proxy_util import strip, request_page, logger
    
    
    class ProxyBaseCrawler(object):
    
        def __init__(self, queue=None, website=None, urls=[]):
            self.queue = queue
            self.website = website
            self.urls = urls
    
        def _start_crawl(self):
            raise NotImplementedError
    
    
    class KuaiDailiCrawler(ProxyBaseCrawler):  # 快代理
        def _start_crawl(self):
            for url_dict in self.urls:
                logger.info("开始爬取 [ " + self.website + " ] :::> [ " + url_dict['type'] + " ]")
                has_more = True
                url = None
                while has_more:
                    if 'page' in url_dict.keys() and str.find(url_dict['url'], '{}') != -1:
                        url = url_dict['url'].format(str(url_dict['page']))
                        url_dict['page'] = url_dict['page'] + 1
                    else:
                        url = url_dict['url']
                        has_more = False
                    html = etree.HTML(request_page(url))
                    tr_list = html.xpath("//table[@class='table table-bordered table-striped']/tbody/tr")
                    for tr in tr_list:
                        ip = tr.xpath("./td[@data-title='IP']/text()")[0] if len(
                            tr.xpath("./td[@data-title='IP']/text()")) else None
                        port = tr.xpath("./td[@data-title='PORT']/text()")[0] if len(
                            tr.xpath("./td[@data-title='PORT']/text()")) else None
                        schema = tr.xpath("./td[@data-title='类型']/text()")[0] if len(
                            tr.xpath("./td[@data-title='类型']/text()")) else None
                        proxy = IPProxy(schema=strip(schema), ip=strip(ip), port=strip(port))
                        if proxy._check_format():
                            self.queue.push(proxy)
                    if tr_list is None:
                        has_more = False
    
    
    class FeiyiDailiCrawler(ProxyBaseCrawler):  # 飞蚁代理
        def _start_crawl(self):
            for url_dict in self.urls:
                logger.info("开始爬取 [ " + self.website + " ] :::> [ " + url_dict['type'] + " ]")
                has_more = True
                url = None
                while has_more:
                    if 'page' in url_dict.keys() and str.find(url_dict['url'], '{}') != -1:
                        url = url_dict['url'].format(str(url_dict['page']))
                        url_dict['page'] = url_dict['page'] + 1
                    else:
                        url = url_dict['url']
                        has_more = False
                    html = etree.HTML(request_page(url))
                    tr_list = html.xpath("//div[@id='main-content']//table/tr[position()>1]")
                    for tr in tr_list:
                        ip = tr.xpath("./td[1]/text()")[0] if len(tr.xpath("./td[1]/text()")) else None
                        port = tr.xpath("./td[2]/text()")[0] if len(tr.xpath("./td[2]/text()")) else None
                        schema = tr.xpath("./td[4]/text()")[0] if len(tr.xpath("./td[4]/text()")) else None
                        proxy = IPProxy(schema=strip(schema), ip=strip(ip), port=strip(port))
                        if proxy._check_format():
                            self.queue.push(proxy)
                    if tr_list is None:
                        has_more = False
    
    
    class WuyouDailiCrawler(ProxyBaseCrawler):  # 无忧代理
        def _start_crawl(self):
            for url_dict in self.urls:
                logger.info("开始爬取 [ " + self.website + " ] :::> [ " + url_dict['type'] + " ]")
                has_more = True
                url = None
                while has_more:
                    if 'page' in url_dict.keys() and str.find(url_dict['url'], '{}') != -1:
                        url = url_dict['url'].format(str(url_dict['page']))
                        url_dict['page'] = url_dict['page'] + 1
                    else:
                        url = url_dict['url']
                        has_more = False
                    html = etree.HTML(request_page(url))
                    ul_list = html.xpath("//div[@class='wlist'][2]//ul[@class='l2']")
                    for ul in ul_list:
                        ip = ul.xpath("./span[1]/li/text()")[0] if len(ul.xpath("./span[1]/li/text()")) else None
                        port = ul.xpath("./span[2]/li/text()")[0] if len(ul.xpath("./span[2]/li/text()")) else None
                        schema = ul.xpath("./span[4]/li/text()")[0] if len(ul.xpath("./span[4]/li/text()")) else None
                        proxy = IPProxy(schema=strip(schema), ip=strip(ip), port=strip(port))
                        if proxy._check_format():
                            self.queue.push(proxy)
                    if ul_list is None:
                        has_more = False
    
    
    class IPhaiDailiCrawler(ProxyBaseCrawler):  # IP海代理
        def _start_crawl(self):
            for url_dict in self.urls:
                logger.info("开始爬取 [ " + self.website + " ] :::> [ " + url_dict['type'] + " ]")
                has_more = True
                url = None
                while has_more:
                    if 'page' in url_dict.keys() and str.find(url_dict['url'], '{}') != -1:
                        url = url_dict['url'].format(str(url_dict['page']))
                        url_dict['page'] = url_dict['page'] + 1
                    else:
                        url = url_dict['url']
                        has_more = False
                    html = etree.HTML(request_page(url))
                    tr_list = html.xpath("//table//tr[position()>1]")
                    for tr in tr_list:
                        ip = tr.xpath("./td[1]/text()")[0] if len(tr.xpath("./td[1]/text()")) else None
                        port = tr.xpath("./td[2]/text()")[0] if len(tr.xpath("./td[2]/text()")) else None
                        schema = tr.xpath("./td[4]/text()")[0] if len(tr.xpath("./td[4]/text()")) else None
                        proxy = IPProxy(schema=strip(schema), ip=strip(ip), port=strip(port))
                        if proxy._check_format():
                            self.queue.push(proxy)
                    if tr_list is None:
                        has_more = False
    
    
    class YunDailiCrawler(ProxyBaseCrawler):  # 云代理
        def _start_crawl(self):
            for url_dict in self.urls:
                logger.info("开始爬取 [ " + self.website + " ] :::> [ " + url_dict['type'] + " ]")
                has_more = True
                url = None
                while has_more:
                    if 'page' in url_dict.keys() and str.find(url_dict['url'], '{}') != -1:
                        url = url_dict['url'].format(str(url_dict['page']))
                        url_dict['page'] = url_dict['page'] + 1
                    else:
                        url = url_dict['url']
                        has_more = False
                    html = etree.HTML(request_page(url, encoding='gbk'))
                    tr_list = html.xpath("//table/tbody/tr")
                    for tr in tr_list:
                        ip = tr.xpath("./td[1]/text()")[0] if len(tr.xpath("./td[1]/text()")) else None
                        port = tr.xpath("./td[2]/text()")[0] if len(tr.xpath("./td[2]/text()")) else None
                        schema = tr.xpath("./td[4]/text()")[0] if len(tr.xpath("./td[4]/text()")) else None
                        proxy = IPProxy(schema=strip(schema), ip=strip(ip), port=strip(port))
                        if proxy._check_format():
                            self.queue.push(proxy)
                    if tr_list is None:
                        has_more = False
    
    
    class XiCiDailiCrawler(ProxyBaseCrawler):  # 西刺代理
        def _start_crawl(self):
            for url_dict in self.urls:
                logger.info("开始爬取 [ " + self.website + " ] :::> [ " + url_dict['type'] + " ]")
                has_more = True
                url = None
                while has_more:
                    if 'page' in url_dict.keys() and str.find(url_dict['url'], '{}') != -1:
                        url = url_dict['url'].format(str(url_dict['page']))
                        url_dict['page'] = url_dict['page'] + 1
                    else:
                        url = url_dict['url']
                        has_more = False
                    html = etree.HTML(request_page(url))
                    tr_list = html.xpath("//table[@id='ip_list']//tr[@class!='subtitle']")
                    for tr in tr_list:
                        ip = tr.xpath("./td[2]/text()")[0] if len(tr.xpath("./td[2]/text()")) else None
                        port = tr.xpath("./td[3]/text()")[0] if len(tr.xpath("./td[3]/text()")) else None
                        schema = tr.xpath("./td[6]/text()")[0] if len(tr.xpath("./td[6]/text()")) else None
                        if schema.lower() == "http" or schema.lower() == "https":
                            proxy = IPProxy(schema=strip(schema), ip=strip(ip), port=strip(port))
                            if proxy._check_format():
                                self.queue.push(proxy)
                    if tr_list is None:
                        has_more = False

    run.py

    通过run.py启动各个代理网站爬虫。

    # -*- coding: utf-8 -*-
    import redis
    from proxy_queue import FifoQueue
    from settings import REDIS_HOST, REDIS_PORT
    from proxy_crawlers import WuyouDailiCrawler, FeiyiDailiCrawler, KuaiDailiCrawler, IPhaiDailiCrawler, YunDailiCrawler, \
        XiCiDailiCrawler
    
    r = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT)
    fifo_queue = FifoQueue(r)
    
    
    def run_kuai():
        kuaidailiCrawler = KuaiDailiCrawler(queue=fifo_queue, website='快代理[国内高匿]',
                                            urls=[{'url': 'https://www.kuaidaili.com/free/inha/{}/', 'type': '国内高匿',
                                                   'page': 1},
                                                  {'url': 'https://www.kuaidaili.com/free/intr/{}/', 'type': '国内普通',
                                                   'page': 1}])
        kuaidailiCrawler._start_crawl()
    
    
    def run_feiyi():
        feiyidailiCrawler = FeiyiDailiCrawler(queue=fifo_queue, website='飞蚁代理',
                                              urls=[{'url': 'http://www.feiyiproxy.com/?page_id=1457', 'type': '首页推荐'}])
        feiyidailiCrawler._start_crawl()
    
    
    def run_wuyou():
        wuyoudailiCrawler = WuyouDailiCrawler(queue=fifo_queue, website='无忧代理',
                                              urls=[{'url': 'http://www.data5u.com/free/index.html', 'type': '首页推荐'},
                                                    {'url': 'http://www.data5u.com/free/gngn/index.shtml', 'type': '国内高匿'},
                                                    {'url': 'http://www.data5u.com/free/gnpt/index.shtml', 'type': '国内普通'}])
        wuyoudailiCrawler._start_crawl()
    
    
    def run_iphai():
        crawler = IPhaiDailiCrawler(queue=fifo_queue, website='IP海代理',
                                    urls=[{'url': 'http://www.iphai.com/free/ng', 'type': '国内高匿'},
                                          {'url': 'http://www.iphai.com/free/np', 'type': '国内普通'},
                                          {'url': 'http://www.iphai.com/free/wg', 'type': '国外高匿'},
                                          {'url': 'http://www.iphai.com/free/wp', 'type': '国外普通'}])
        crawler._start_crawl()
    
    
    def run_yun():
        crawler = YunDailiCrawler(queue=fifo_queue, website='云代理',
                                  urls=[{'url': 'http://www.ip3366.net/free/?stype=1&page={}', 'type': '国内高匿', 'page': 1},
                                        {'url': 'http://www.ip3366.net/free/?stype=2&page={}', 'type': '国内普通', 'page': 1},
                                        {'url': 'http://www.ip3366.net/free/?stype=3&page={}', 'type': '国外高匿', 'page': 1},
                                        {'url': 'http://www.ip3366.net/free/?stype=4&page={}', 'type': '国外普通', 'page': 1}])
        crawler._start_crawl()
    
    
    def run_xici():
        crawler = XiCiDailiCrawler(queue=fifo_queue, website='西刺代理',
                                   urls=[{'url': 'https://www.xicidaili.com/', 'type': '首页推荐'},
                                         {'url': 'https://www.xicidaili.com/nn/{}', 'type': '国内高匿', 'page': 1},
                                         {'url': 'https://www.xicidaili.com/nt/{}', 'type': '国内普通', 'page': 1},
                                         {'url': 'https://www.xicidaili.com/wn/{}', 'type': '国外高匿', 'page': 1},
                                         {'url': 'https://www.xicidaili.com/wt/{}', 'type': '国外普通', 'page': 1}])
        crawler._start_crawl()
    
    
    if __name__ == '__main__':
        run_xici()
        run_iphai()
        run_kuai()
        run_feiyi()
        run_yun()
        run_wuyou()

    爬取西刺代理时,后台日志示例如下:

    Redis数据库中爬取到的代理IP的数据结构如下:

    四、代理测试

     接下来,使用爬取好的代理来请求 http://icanhazip.com 进行测试,代码如下:

    # -*- coding: utf-8 -*-
    import random
    import requests
    from proxy_util import logger
    from run import fifo_queue
    from settings import USER_AGENT_LIST
    from proxy_util import base_headers
    
    # 测试地址
    url = 'http://icanhazip.com'
    
    # 获取代理
    proxy = fifo_queue.pop(schema='http')
    proxies = {proxy.schema:proxy._get_url()}
    
    # 构造请求头
    headers = dict(base_headers)
    if 'User-Agent' not in headers.keys():
        headers['User-Agent'] = random.choice(USER_AGENT_LIST)
    
    response = None
    successed = False
    try:
        response = requests.get(url,headers=headers,proxies = proxies,timeout=5)
    except BaseException:
        logger.error("使用代理< "+proxy._get_url()+" > 请求 < "+url+" > 结果: 失败 ")
    else:
        if (response.status_code == 200):
            logger.info(response.content.decode())
            successed = True
            logger.info("使用代理< " + proxy._get_url() + " > 请求 < " + url + " > 结果: 成功 ")
        else:
            logger.info(response.content.decode())
            logger.info("使用代理< " + proxy._get_url() + " > 请求 < " + url + " > 结果: 失败 ")
    
    # 根据请求的响应结果更新代理
    proxy._update(successed)
    # 将代理返还给队列,返还时不校验可用性
    fifo_queue.push(proxy,need_check=False)

     使用 http://218.66.253.144:80 代理请求成功后将代理重新放回队列,并将 Redis 中该代理的 used_total 、success_times 、continuous_failed三个字段信息进行了相应的更新。

    项目地址:https://github.com/pengjunlee/ipproxy_pool.git

    展开全文
  • 如何建立爬虫代理ip池

    万次阅读 2019-04-10 09:08:20
    一、为什么需要建立爬虫代理ip池 二、如何建立一个爬虫代理ip池 原文地址:https://www.cnblogs.com/TurboWay/p/8172246.html 一、为什么需要建立爬虫代理ip池 在众多的网站防爬措施中,有一种是根据ip的访问...

    目录

    一、为什么需要建立爬虫代理ip池

    二、如何建立一个爬虫代理ip池      


    原文地址:https://www.cnblogs.com/TurboWay/p/8172246.html 

    一、为什么需要建立爬虫代理ip池

                  在众多的网站防爬措施中,有一种是根据ip的访问频率进行限制的,在某段时间内,当某个ip的访问量达到一定的阀值时,该ip会被拉黑、在一段时间内被禁止访问。

    这种时候,可以通过降低爬虫的频率,或者更改ip来应对。后者就需要有一个可用的代理ip池,以供爬虫工作时切换。

    二、如何建立一个爬虫代理ip池      

    思路:

    1、找到一个免费的ip代理网站(如:西刺代理)

    2、爬取ip(常规爬取requests+BeautifulSoup)

    3、验证ip有效性(携带爬取到的ip,去访问指定的url,看返回的状态码是不是200)

    4、记录ip (写到文档)

    代码如下:

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    import requests,threading,datetime
    from bs4 import BeautifulSoup
    import random
    
    """
    1、抓取西刺代理网站的代理ip
    2、并根据指定的目标url,对抓取到ip的有效性进行验证
    3、最后存到指定的path
    """
    
    # ------------------------------------------------------文档处理--------------------------------------------------------
    # 写入文档
    def write(path,text):
        with open(path,'a', encoding='utf-8') as f:
            f.writelines(text)
            f.write('\n')
    # 清空文档
    def truncatefile(path):
        with open(path, 'w', encoding='utf-8') as f:
            f.truncate()
    # 读取文档
    def read(path):
        with open(path, 'r', encoding='utf-8') as f:
            txt = []
            for s in f.readlines():
                txt.append(s.strip())
        return txt
    # ----------------------------------------------------------------------------------------------------------------------
    # 计算时间差,格式: 时分秒
    def gettimediff(start,end):
        seconds = (end - start).seconds
        m, s = divmod(seconds, 60)
        h, m = divmod(m, 60)
        diff = ("%02d:%02d:%02d" % (h, m, s))
        return diff
    # ----------------------------------------------------------------------------------------------------------------------
    # 返回一个随机的请求头 headers
    def getheaders():
        user_agent_list = [ \
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1" \
            "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11", \
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6", \
            "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6", \
            "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1", \
            "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5", \
            "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5", \
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", \
            "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", \
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", \
            "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3", \
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3", \
            "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", \
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", \
            "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", \
            "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3", \
            "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24", \
            "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
        ]
        UserAgent=random.choice(user_agent_list)
        headers = {'User-Agent': UserAgent}
        return headers
    # -----------------------------------------------------检查ip是否可用----------------------------------------------------
    def checkip(targeturl,ip):
        headers =getheaders()  # 定制请求头
        proxies = {"http": "http://"+ip, "https": "http://"+ip}  # 代理ip
        try:
            response=requests.get(url=targeturl,proxies=proxies,headers=headers,timeout=5).status_code
            if response == 200 :
                return True
            else:
                return False
        except:
            return False
    
    #-------------------------------------------------------获取代理方法----------------------------------------------------
    # 免费代理 XiciDaili
    def findip(type,pagenum,targeturl,path): # ip类型,页码,目标url,存放ip的路径
        list={'1': 'http://www.xicidaili.com/nt/', # xicidaili国内普通代理
              '2': 'http://www.xicidaili.com/nn/', # xicidaili国内高匿代理
              '3': 'http://www.xicidaili.com/wn/', # xicidaili国内https代理
              '4': 'http://www.xicidaili.com/wt/'} # xicidaili国外http代理
        url=list[str(type)]+str(pagenum) # 配置url
        headers = getheaders() # 定制请求头
        html=requests.get(url=url,headers=headers,timeout = 5).text
        soup=BeautifulSoup(html,'lxml')
        all=soup.find_all('tr',class_='odd')
        for i in all:
            t=i.find_all('td')
            ip=t[1].text+':'+t[2].text
            is_avail = checkip(targeturl,ip)
            if is_avail == True:
                write(path=path,text=ip)
                print(ip)
    
    #-----------------------------------------------------多线程抓取ip入口---------------------------------------------------
    def getip(targeturl,path):
         truncatefile(path) # 爬取前清空文档
         start = datetime.datetime.now() # 开始时间
         threads=[]
         for type in range(4):   # 四种类型ip,每种类型取前三页,共12条线程
             for pagenum in range(3):
                 t=threading.Thread(target=findip,args=(type+1,pagenum+1,targeturl,path))
                 threads.append(t)
         print('开始爬取代理ip')
         for s in threads: # 开启多线程爬取
             s.start()
         for e in threads: # 等待所有线程结束
             e.join()
         print('爬取完成')
         end = datetime.datetime.now() # 结束时间
         diff = gettimediff(start, end)  # 计算耗时
         ips = read(path)  # 读取爬到的ip数量
         print('一共爬取代理ip: %s 个,共耗时: %s \n' % (len(ips), diff))
    
    #-------------------------------------------------------启动-----------------------------------------------------------
    if __name__ == '__main__':
        path = 'ip.txt' # 存放爬取ip的文档path
        targeturl = 'http://www.cnblogs.com/TurboWay/' # 验证ip有效性的指定url
        getip(targeturl,path)

    结果:

     

     

    展开全文
  • 随着互联网的发展进步,现在互联网上也有许多网络爬虫。网络爬虫通过自己爬虫程序...当然每个人的爬虫程序不同,使用爬虫代理用法也不同。 互联网也有常见的爬虫代理使用方式: 1、传统的API提取的优质代理(传统API提取

    随着互联网的发展进步,现在互联网上也有许多网络爬虫。网络爬虫通过自己爬虫程序向目标网站采集相关数据信息。当然互联网的网站会有反爬策略。比如某电商网站就会限制一个用户IP的访问频率,从而出现验证码。就算验证码通过了,也不会采集到数据,这也就是所谓的反爬虫策略。所以这种情况下,越来越多的网络爬虫会利用代理IP去进行采集。目标网站限制了一个IP,可以换一个代理IP继续进行业务采集。当然每个人的爬虫程序不同,使用爬虫代理用法也不同。
    互联网也有常见的爬虫代理使用方式:
    1、传统的API提取的优质代理(传统API提取式代理,通过URL定时获取代理IP信息,需验证IP的可用性、更换代理设置,同时需要设计多线程异步IO,实现代理IP并发处理,不仅繁琐,而且影响效率。)
    2、自动转发的爬虫代理(自动转发的爬虫代理IP”通过固定云代理服务地址,建立专线网络链接,代理平台自动实现毫秒级代理IP切换,保证了网络稳定性和速度,避免爬虫客户在代理IP策略优化上投入精力。)
    以上是市面上常见的使用爬虫代理方式,针对每个爬虫应用环境和接口不同,需要选择适合自己程序的代理使用方式。
    很多爬虫都会选择通过代理商提供的API链接获取代理IP,放在自己的搭建的IP池内进行管理,从而发出请求进行数据采集。当然也有很多爬虫不愿意自己做IP池管理,觉得那种方式使用麻烦。想直接利用代理IP去发出请求获取数据。这时候就需要用自动转发的爬虫代理,代理供应商就会提供一个代理服务器域名信息和用户名、密码。就是比传统的API代理,多了一个认证信息。
    在nodejs爬虫中,可以用axios中的proxyhost和proxyport来设置代理服务器,proxyUser和proxyPass设置用户名和密码进行认证。
    以下是关于nodejs爬虫使用axios如何配置爬虫代理dmeo:
    const axios = require(‘axios’);
    // 要访问的目标页面
    const targetUrl = “http://httpbin.org/ip”;
    // 代理服务器(产品官网 www.16yun.cn)
    const proxyHost = “t.16yun.cn”;
    const proxyPort = 31111;
    // 代理验证信息
    const proxyUser = “username”;
    const proxyPass = “password”;
    var proxy = {
    host: proxyHost,
    port: proxyPort,
    auth: {
    username: proxyUser,
    password: proxyPass
    }
    };
    axios.get(targetUrl,{proxy:proxy})
    .then(function (response) {
    // handle success
    console.log(response.data);
    })
    .catch(function (error) {
    // handle error
    console.log(error);
    })
    .finally(function () {
    // always executed
    });
    每个爬虫的程序使用的语言框架都不同,以上是比较偏门的爬虫语言框架配置爬虫代理的demo。其他语言配置爬虫代理的demo可以参考以上demo分析百度。

    展开全文
  • 网络爬虫代理

    2019-03-04 17:40:13
    我们知道,代理ip按照匿名程度来分可以分为透明代理、普匿代理和高匿代理...“亿牛云爬虫代理IP”通过固定云代理服务地址,建立专线网络链接,代理平台自动实现毫秒级代理IP切换,保证了网络稳定性和速度,避免爬虫...
  • 什么是隧道代理:客户计算机通过专线网络链接固定代理服务器(固定IP),固定...什么是爬虫代理爬虫代理通过固定云代理服务地址,建立专线网络链接,代理平台自动实现毫秒级代理IP切换,保证了网络稳定性和速度...
  • 爬虫代理IP的使用+建立代理IP池代理IP的使用建立代理IP池完整代码 代理IP的使用 先了解一下百度百科定义的IP 为什么要使用代理IP? 反爬(反网络爬虫) 示例: 测试网址 http://httpbin.org/get 浏览器先...
  • 爬虫代理IP池

    2019-01-10 15:49:55
    爬虫代理IP池介绍源码获取方式 介绍 通过爬虫技术获取有效的代理IP,基于Python-tornado的API框架对代理IP进行操作,详情请浏览项目Git 源码获取方式 Git : https://github.com/tangchen2018/proxy_pool_tornado.git...
  • python爬虫代理服务器的使用
  • Python爬虫代理

    千次阅读 2019-01-25 14:30:09
    爬虫代理IP池 在公司做分布式深网爬虫,搭建了一套稳定的代理池服务,为上千个爬虫提供有效的代理,保证各个爬虫拿到的都是对应网站有效的代理IP,从而保证爬虫快速稳定的运行,当然在公司做的东西不能开源出来。...
  • squid爬虫代理自动轮询转发

    千次阅读 2019-09-23 21:02:10
    squid在做爬虫代理时候,我们只需要做到一个squid代理,然后对其他代理做转发轮询,如何使用squid做代理并自动转发轮询?加上这行代码: cache_peer 120.xx.xx.32 parent 80 0 no-query weighted-round-robin weight...
  • 用过代理IP的用户都知道,市面上有两种代理,一种是传统的API代理,另一种是自动转发毫秒级切换的爬虫代理(分为爬虫基础版、爬虫标准版和爬虫加强版)。亿牛云代理两种模式都支持 API代理分为外网IP和隧道IP。API...
  • selenium+python设置爬虫代理IP

    万次阅读 2017-11-24 17:35:51
    selenium+python设置爬虫代理IP 1. 背景 在使用selenium浏览器渲染技术,爬取网站信息时,一般来说,速度是很慢的。而且一般需要用到这种技术爬取的网站,反爬技术都比较厉害,对IP的访问频率应该有相当的限制。...
  • 从零教你建立爬虫代理ip池

    千次阅读 2020-06-30 15:00:28
    一、为什么需要建立爬虫代理ip池 在众多的网站防爬措施中,有一种是根据ip的访问频率进行限制的,在某段时间内,当某个ip的访问量达到一定的阀值时,该ip会被拉黑、在一段时间内被禁止访问。 这种时候,可以通过...
  • 十万火急的数据采集项目,爬虫代理测试对比 开春上班第一天,正在喝咖啡发神,老大开会宣布公司要重点投入数据爬取和分析业务,为客户做业务做数据支撑要求达到日均1000W级别的数据采集量,让我做一下技术规划。赶紧...
  • 爬虫代理池的使用

    2020-01-04 22:30:27
    用于解决爬虫时访问频率过高封ip的问题 前期准备 1.需要准备一个代理池,可以自己爬取一些IP做一个代理池(简单的做法可以是把IP放到txt文件读取,也可以自己使用开源代理池代码(借用别人做的代理池,不同代码效率有...
  • 搭建爬虫代理

    千次阅读 2020-05-29 17:16:42
    刚自学爬虫的时候没有代理IP就去西刺有免费代理的网站去爬,还是有个别代理能用。当然,如果你有更好的代理接口也可以自己接入例如(亿牛云代理) 免费代理的采集也很简单,无非就是:访问页面页面 —> 正则/...
  • 当我们对某些网站进行爬去的时候,我们经常会换IP来避免爬虫程序被封锁。代理ip地址如何获取?其实也是一个比较简单的操作,目前网络上有很多IP代理商,例如西刺,芝麻,犀牛等等。这些代理商一般都会提供透明代理,...
  • java爬虫代理

    千次阅读 2017-10-26 11:02:25
    爬虫程序中怎么加入动态代理  网络编程 2013-04-02 13:04:51 14151 5评论 下载为PDF  相信很多人都用过代码写过不同的爬虫程序吧,来获取互联网上自己需要的信息,这比自己手动的去一个一个复制来的容易。...
  • 爬虫代理的使用方法

    2019-06-27 17:46:54
    在日常的网络工作中,很多网络工作者需要使用到代理IP来辅助完成任务,如比较常见的爬虫工作、营销发帖、网络投票、效果补量等,有是使用第三方工具,有的自己编写代码程序,通过对接API自动调用来获取IP,然后完成...
  • 做网络爬虫时,通常对代理IP的需要量比较大。由于在爬取网站信息内容的过程中,许多 网站做了反爬虫策略,可能会对每个IP做频次控制。这样我们在爬取网站时就需要许多代理IP。 代理IP的获取,可以从以下几个途径...
  • 爬虫代理池完全教程

    万次阅读 多人点赞 2018-03-05 21:53:07
    在编写爬虫的过程中我们经常会遇到需要代理的情况,代理可以到网上找免费的也可以用付费的。付费的使用网站提供的API就可以轻松获取代理,免费的就只能到处找然后采集而且代理质量还不高(付费的也不一定好)。但是...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 46,744
精华内容 18,697
关键字:

爬虫代理

爬虫 订阅