zoukankan      html  css  js  c++  java
  • 爬虫

    应对反爬

    更换ip地址

    比如我用requests来发送请求

    import requests
    
    proxies = {
      "http": "http://10.10.1.10:3128",
      "https": "http://10.10.1.10:1080",  # 这里用 https 代理会失效,取的是 https ip 也不行,可能我爬取的是 http 网站(猜测)
    }
    
    requests.get("http://example.org", headers=headers, proxies=proxies)
    

    参数proxies就是更换的代理ip,注意格式里https的头还是http

    至于ip怎么搞,一些卖ip的网站首页上有免费的ip可以用,写了个爬虫爬下来用
    后来可能是爬多了,别人把我封了,就花钱买了ip
    这里推荐一下大象代理,http://www.daxiangdaili.com
    五块钱两万个ip,可能不太稳定,但自己用应该够了

    requests文档
    http://docs.python-requests.org/zh_CN/latest/user/advanced.html#proxies

    更换UserAgent

    User-Agent 首部包含了一个特征字符串,用来让网络协议的对端来识别发起请求的用户代理软件的应用类型、操作系统、软件开发商以及版本号。

    我是这么做的
    去网上复制十几个UserAgent,放到列表里,每次从中随机取一个

    from random import choice
    
    ua_list = [
        'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
        'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
        'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv,2.0.1) Gecko/20100101 Firefox/4.0.1',
        'Mozilla/5.0 (Windows NT 6.1; rv,2.0.1) Gecko/20100101 Firefox/4.0.1',
        'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;',
        'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)',
        'Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11',
        'Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11',
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',
        'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Maxthon 2.0)',
        'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)',
        'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SE 2.X MetaSr 1.0; SE 2.X MetaSr 1.0; .NET CLR 2.0.50727; SE 2.X MetaSr 1.0)',
        'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)',
        'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Maxthon 2.0)',
    ]
    
    def ua_get():
        ua = choice(ua_list)
        headers = {"User-Agent": ua, }
        return headers
    

    看到更骚的操作是,使用搜索引擎爬虫的UserAgent
    试了一下,但会报错,就没去深究了

    redis 代理ip池

    之前的做法是每次从代理接口取一个ip,所有的请求都用这一个ip去伪装
    问题是,取的间隔至少得一秒,如果这个ip不能用或者速度慢,那这一秒内的请求全部不能用,并且会一直请求到超时
    既然用的是五块钱两万个ip,那肯定一大堆不能用的

    所以去网上看了别人的做法,然后按自己的想法做了一个ip池
    具体做法是

    每次从接口取10个ip,放进redis里,取的方式是先进后出,每次从头部取
    设置请求的时间,如果请求超时或者报错了,就重新取一个ip再发请求
    限制发送次数,超过次数就退出来
    如果请求发送成功,拿到了想要的东西,就把那个能用的ip从尾部塞回去
    如果去redis取ip的时候发现空了,就重新去接口拿10个

    整个过程就是这样,贴一个丑陋的函数

    def requests_send(url):
        h = header_get()
        code = 0
        count = 0
        while code != 200:  # 如果请求不成功,就接着请求下去
            count += 1
            print('第{}次请求'.format(count))
            if count > 10:  # 限制次数
                break
            try:
                ip = pop()  # 取ip
                p = dict(http='http://{}'.format(ip))
                print('proxy', p)
                r = requests.get(url, headers=h, proxies=p, timeout=3)  # 发送请求
                response = r.content.decode('utf-8')
                code = r.status_code
                path = response
            except Exception as err:  # 报错了的话,也会重新请求
                print(str(err))
            else:
                print('path[-4:]', path[-4:])
                if path[-4:] != '.mp3':  # 如果没拿到想要的,重新开始一次
                    continue
                rds.rpush('ip-proxy-pool', ip)  # 成功了把ip塞回去
                print('补充1个', ip)
                return dict(code=200, path=path)
        return dict(code=-1)
    

    这种做法并不好,有条件的话,应该时刻保持着ip能用,但那样的话请求量就陡增了很多

    文档
    https://cloud.tencent.com/developer/article/1004915
    https://www.jianshu.com/p/588241a313e7

  • 相关阅读:
    iOS 面试题搜集
    iOS 常用第三方类库、完整APP示例
    iOS 键盘遮挡输入 解决办法
    iOS UIColor RGB HEX
    iOS APP性能优化
    iOS Swift 数组 交换元素的两种方法
    iOS CoreData primitive accessor
    iOS Start developing ios apps (OC) pdf
    iOS 传值方式
    iOS IB_DESIGNABLE IBInspectable @IBDesignable @IBInspectable 加速UI开发
  • 原文地址:https://www.cnblogs.com/xb21/p/8386111.html
Copyright © 2011-2022 走看看