爬虫入门学习(七)IP学习与代理池构建

23 篇文章 4 订阅

1 IP简介

互联网协议地址(英语:Internet Protocol Address,又译为网际协议地址),缩写为IP地址(英语:IP Address),是分配给网络上使用网际协议(英语:Internet Protocol, IP)的设备的数字标签。常见的IP地址分为IPv4与IPv6两大类,但是也有其他不常用的小分类。(via Wiki)
IP是TCP/IP协议栈中最核心的协议之一,通过IP地址,保证了联网设备的唯一性,实现了网络通信的面向无连接和不可靠的传输功能。解决不可靠问题通过TCP实现
IP地址是唯一的。当前IPv4技术可能使用的IP地址最多可有4,294,967,296个(即232)。科研组织已研究出128位的IPv6,其IP地址数量最高可达3.402823669 × 1038个,届时每个人家居中的每件电器,每件对象,甚至地球上每一粒沙子都可以拥有自己的IP地址。

  • IP地址
    (1) IP地址由32位二进制数组成,为便于使用,常以XXX.XXX.XXX.XXX形式表现,每组XXX代表小于或等于255的10进制数。地址可分为A、B、C、D、E五大类,其中E类属于特殊保留地址。
    (2)用来在网络中标记一台电脑的一串数字,每个IP地址包括两部分,网络地址主机地址。网络地址的最高位必须是0。
    (3)子网掩码的作用是将IP地址划分成网络地址和主机地址两部分。子网掩码不能单独存在,必须与IP地址一起使用。
    (4)主机号全为0,表示网络号;主机号全为1,表示网络广播

2 IP被封的原因

  • IP封锁
    IP封锁是指防火墙维护一张IP黑名单,一旦发现发往黑名单中地址的请求数据包,就直接将其丢弃,这将导致源主机得不到目标主机的及时响应而引发超时,从而达到屏蔽对目标主机的访问的目的。
  • 原因
    (1)针对爬虫而言,最常见是服务器采取了反爬虫措施,比如:通过检测User-Agent字段、限制单位时间内的访问次数,如果单位时间内访问次数过于频繁则被认定为爬虫等,从而导致IP被封
    (2)服务器在国内被封,无法正常访问。
    (3)服务商更换服务器(不常见)。

3 应对IP被封的策略

在写爬虫时,可以先通过查看robots协议,查看该网站的禁止爬的网页。然后我们就针对服务器常用的反爬虫措施来进行反反爬虫,从而避免爬虫爬着爬着就被禁了。服务器在这个攻防中是弱势一方,因为服务器的目的就是提供服务的,除非它不打算为客服服务了,所以爬虫需要做的就是模拟真实人的访问,那么服务器就无可奈何了。

3.1 伪造User-Agent

在请求头中把User-Agent设置成浏览器中的User-Agent,来伪造浏览器访问。这是非常常用的方法。
更有效的措施是构建一个User-Agent池,每次请求时随机从中选择一个使用,这样可以进一步提高安全性。

# 构建User-Agent
import requests
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) \
           AppleWebKit/537.36 (KHTML, like Gecko) \
           Chrome/73.0.3683.86 Safari/537.36'}
resp = requests.get(url,headers=headers)  
# 构建多个User-Agent,随机使用
import random
def get_headers():
    '''
    随机获取一个headers
    '''
    user_agents = ['Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 \
                    Firefox/4.0.1','Mozilla/5.0 \
                    (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 \
                    (KHTML, like Gecko) Version/5.1 Safari/534.50',\
                    'Opera/9.80 (Windows NT 6.1; U; en)\
                    Presto/2.8.131 Version/11.11']
    headers = {'User-Agent':random.choice(user_agents)}
    return headers

注:一些常见浏览器的User-Agent可参见:User-Agent结构介绍及主流浏览器User-Agent大全

3.2 设置线程等待sleep()

在每次重复爬取时设置一个随机间隔,模拟人的访问频率,避免被禁止。可以再多线程爬虫中配合使用。

time.sleep(random.randint(0,3))  # 线程暂停0~3秒的整数秒,时间区间[0,3]
time.sleep(random.random())   # 暂停0~1秒的小数,时间区间:[0,1)

3.3 伪造Cookies

伪造Cookies也是另一个常用的方法。不过前提是这个Cookies可以正常访问页面。

cookies = dict(uuid='b18f0e70-8705-470d-bc4b-09a8da617e15',\
               UM_distinctid='15d188be71d50-013c49b12ec14a-\
               3f73035d-100200-15d188be71ffd')
response = requests.get(url,cookies=cookies)
# 把浏览器的cookies字符串转成字典
def cookies2dict(cookies):
    items = cookies.split(';')
    d = {}
    for item in items:
        kv = item.split('=',1)
        k = kv[0]
        v = kv[1]
        d[k] = v
    return d

注:用浏览器cookies发起请求后,如果请求频率过于频繁仍会被封IP,这时可以在浏览器上进行相应的手工验证(比如点击验证图片等),然后就可以继续正常使用该cookies发起请求。

3.4 使用代理

通过换IP可以防止同一个IP多次请求而被服务器封IP。不过需要先构建一个可用的IP池。

proxies = {'http':'http://10.10.10.10:8765','https':'https://10.10.10.10:8765'}
response = requests.get(url,proxies = proxies)

道高一尺魔高一丈,你有反爬虫措施,那我也有各种"反反爬虫"的措施,GitHub上就有一位大神专门整理了一个这样的项目:Anti-Anti-Spider

4 抓取西刺代理,并构建自己的代理池

目的:抓取西刺代理,并构建自己的代理池
西刺代理官网
因为这里没有爬取更多的IP,所以这里直接采用的re来匹配IP。
完整代码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@author: Jock
"""

import requests
import traceback
import re
import time

class GetIP():
    def __init__(self):
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 \
            (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'
        }

    def get_html(self, url):
        print('正在下载页面:{}'.format(url))
        try:
            r = requests.get(url, headers=self.headers)  # 爬取完整的网页数据
            r.raise_for_status()  # 如果状态不是200,引发HTTPError异常
            return r.text  # 以字符串的形式返回爬取的网页内容
        except Exception:
            print('下载页面出错:{}'.format(url))
            traceback.print_exc()

    def get_ip_list(self, url):
        data = self.get_html(url)
        pat_1 = re.compile(r'/></td>(.*?)</tr>', re.S)  # 构建、编译第一层正则表达式,匹配一个IP完整信息块
        pat_2 = re.compile(r'<td>(.*?)</td>', re.S)  # 构建、编译第二层正则表达式,提取完整的IP信息
        iter_ip = pat_1.finditer(data)  # 找到所有IP信息块,返回生成器
        list_ip = []  # 存放IP
        # 遍历iter_ip,提取并存入IP
        for i in iter_ip:
            try:
                key = pat_2.findall(i.group())
                list_ip.append(key[3].lower() + '://' + key[0] + ':' + key[1])
            except:
                print('解析IP地址出错')
                traceback.print_exc()
                continue
        return list_ip


def main():
    url = 'https://www.xicidaili.com/'
    ip = GetIP()
    list_ip = ip.get_ip_list(url)
    for i in list_ip:
        print(i)
        time.sleep(0.1)

if __name__ == '__main__':
    main()

运行结果:

正在下载页面:https://www.xicidaili.com/
http://27.29.45.59:9999
http://110.52.235.139:9999
https://223.241.78.26:8010
http://27.29.45.83:9999
https://110.52.235.114:9999
https://183.148.135.171:9999
https://183.148.140.128:9999
https://27.29.44.178:9999
https://112.85.131.235:9999
https://27.29.45.56:9999
https://110.52.235.245:9999
https://221.206.100.133:34073
http://183.148.159.210:9999
http://27.29.44.188:9999
http://27.29.45.92:9999
......

5. 参考资料

  1. python爬虫防止IP被封的一些措施
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值