开发者社区> sixkery> 正文

scrapy突破反爬的几种方式(二)

简介: 上回说到设置随机 User-Agent ,这次来一个随机代理 ip 的设置。 代理ip 在爬虫中,为了避免网站将我们的 ip 封掉,我们就要使用代理 ip 。
+关注继续查看

上回说到设置随机 User-Agent ,这次来一个随机代理 ip 的设置。

代理ip

在爬虫中,为了避免网站将我们的 ip 封掉,我们就要使用代理 ip 。虽然说代理 ip 没有原装的好,但是有些时候还是要使用代理ip 来获取数据的。

原理

随机代理 ip 简单来说就是爬取网上的免费代理ip ,然后存入数据库,在数据库中随机拿到一个代理ip来用。具体结合到 scrapy 中,我们就要在 Middleware.py 文件中修改,原理跟上文代理的设置一样,不懂的可以去上篇文章看一下。

实战演练

在上文的 scrapydownloadertest 项目基础上操作。
在 spiders 的同级目录下,新建一个 Python Package 。还要新建python文件,具体名称参考图片。目录结构如下:


img_d94145eb7d5364608e09d805a69c7e3d.png
目录结构

从西刺网上获取免费的代理ip 保存到数据库中。

import requests
from scrapy.selector import Selector
import pymysql

# 连接数据库
conn = pymysql.connect(host='',user='',password='',db='proxy',charset='utf8')
cursor = conn.cursor()
# 爬取西刺网站上的代理ip

def crawler_ips():
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'
    }
    for i in range(100):
        url = 'http://www.xicidaili.com/nn/'.format(i)
        r = requests.get(url,headers=headers)
        selector = Selector(text=r.text)
        all_ips = selector.css('#ip_list tr')
        ip_list = []
        for tr in all_ips[1:]: # 这里由于第一个是标题,舍弃
            speed_str = tr.css('.bar::attr(title)').extract_first()[0]
            if speed_str:
                speed = float(speed_str.split('秒')[0])
            all_texts = tr.css('td::text').extract()

            ip = all_texts[0]
            port = all_texts[1]
            proxy_type = all_texts[5]

            ip_list.append((ip,port,proxy_type,speed))

        for ip_info in ip_list:
            # 插入数据
            cursor.execute(
                "insert proxy_ip(ip,port,speed,proxy_type) VALUES('{0}','{1}',{2},'HTTP')".format(
                ip_info[0],ip_info[1],ip_info[3]
                )
            )
            conn.commit()

数据库我用的是MySQL,在 navivat for mysql 中连接 MySQL ,新建一个数据库,名称随意,这里就叫做 proxy 吧,在代码中把连接数据库的代码补充完整。
新建一个数据表 proxy_ip 并写下如下字段:


img_26a607a5c90f8a28c5fbb7f708a24f83.png
proxy_ip

这里我已经新建好了,并且运行的代码。

新建之后,我们运行上述代码,这时候会看到数据库中已经有了数据。接下来就是从数据库中随机获取一个代理 ip ,供我们程序使用。


class GetIP(object):
    def get_random_ip(self):
        # 从数据库中随机获取一个可用ip
        random_sql = 'SELECT ip,port FROM proxy_ip ORDER BY RAND() LIMIT 1'
        result = cursor.execute(random_sql)
        for ip_info in cursor.fetchall():
            ip = ip_info[0]
            port = ip_info[1]
            judge_re = self.judge_ip(ip,port)
            if judge_re:
                return 'http://{0}:{1}'.format(ip,port)
            else:
                return self.get_random_ip()

    def judge_ip(self,ip,port):
        # 判断ip 是否可用
        http_url = 'http://www.baidu.com'
        proxy_url = 'http://{0}:{1}'.format(ip,port)
        try:
            proxy_dict = {
                'http':proxy_url
            }
            r = requests.get(http_url,proxies=proxy_dict)
            print('effective ip')
            return True
        except Exception as e:
            print('invalid ip and port 无效')
            self.delete_ip(ip)
            return False
        else:
            code = r.status_code
            if code >= 200 and code < 300:
                print('effective ip')
                return True
            else:
                print('invalid ip and port 无效')
                self_delete_ip(ip)
                return False


    def delete_ip(self,ip):
        # 删除无效的ip
        delete_sql = "delete from proxy_ip where ip = '{0}'".format(ip)
        cursor.execute(delete_sql)
        conn.commit()

if __name__ == '__main__':
    get_ip = GetIP()
    print(get_ip.get_random_ip())

这里从数据库中随机获取一个代理ip,并测试代理ip是否可用,不可用的删掉。这里有个小技巧,如果你爬取的是其他网站,就把百度的链接换成你要爬取的网站,这样会提高代理ip的可用性。
运行此代码会随机获取一个可用的ip代理。

接下来在 Middleware.py 中把代理ip 加上:

class RandomProxyMiddleware(object):
    # 动态设置ip代理
    def process_request(self, request, spider):
        get_ip = GetIP()

        request.meta['proxy'] = get_ip.get_random_ip()

在 settings.py 文件中配置一下:


DOWNLOADER_MIDDLEWARES = {
    'scrapy.contrib.downloadermiddleware.useragent.UserAgentMiddleware': None,
    'scrapydownloadertest.middlewares.RandomUserAgentMiddleware': 543,
    'scrapydownloadertest.middlewares.RandomProxyMiddleware': 544,

}

运行spider文件,就可以在输出的日志上面看到代理ip在使用了。

2018-09-16 16:57:46 [urllib3.connectionpool] DEBUG: http://123.249.88.153:9000 "GET http://www.baidu.com/ HTTP/1.1" 200 None
effective ip

总结

  • 使用这样的方法可以用到代理 ip 从而有效的隐藏了自己的真实 ip 。免费从网上获取的代理通常来说没有付费得到的 ip 稳定性好。如果有条件,还是建议自费获取一些代理 ip。

  • 自己的代理还是最好用的,我们在爬取的时候可以放慢速度,增加延迟等方式以避免自己的 ip 被封。同时不要让网站的压力太大。这样才能共存。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
使用 Scrapy 框架来爬取数据
创建一个 Scrapy 项目,项目文件可以直接用 scrapy 命令生成,命令如下所示:scrapy startproject doubanmovie250 这个命令可以在任意文件夹运行。如果提示权限问题,可以加 sudo 运行该命令。
88 0
「Python」爬虫-9.Scrapy框架的初识-公交信息爬取
本文将讲解如何使用scrapy框架完成北京公交信息的获取。
352 0
Python爬虫:scrapy直接运行爬虫
Python爬虫:scrapy直接运行爬虫
136 0
Python爬虫:scrapy防止爬虫被禁的策略
Python爬虫:scrapy防止爬虫被禁的策略
170 0
python爬虫:scrapy命令失效,直接运行爬虫
python爬虫:scrapy命令失效,直接运行爬虫
126 0
Scrapy爬取makepolo网站数据深入详解
题记 之前对爬虫只是概念了解多,实战少。知道网上流行的有号称免费的八爪鱼等(实际导出数据收费)。 大致知道,所有爬虫要实现爬取网页信息,需要定义正则匹配规则。
127 0
Crawler之Scrapy:Python实现scrapy框架爬虫两个网址下载网页内容信息
Crawler之Scrapy:Python实现scrapy框架爬虫两个网址下载网页内容信息
91 0
scrapy突破反爬的几种方式(三)
一些小的技巧配置,让我们的爬虫被识别的概率降低。 cookies 的禁用 在settings.py 文件中有一个参数是: COOKIES_ENABLED = False 默认情况下是禁用的,request 就不会把 cookies 带进去。
1124 0
scrapy突破反爬的几种方式(一)
最近在学习 scrapy 中,突破反爬限制的几种方法,总结一下,记录学习过程中的收获。 在以后的学习中也有可能会用到这些知识。 Downloader Middleware 简单介绍一下 Downloader Middleware 即下载中间件,它处于 Scrapy 的 Request 和 Response 之间的处理模块,在 scrapy 的整个架构中起作用的位置是以下两个 在Scheduler 调度出队列的 Request 发给 Downloader 下载之前,也就是我们可以在 Request 执行下载之前对其进行修改。
1518 0
爬虫进阶:Scrapy抓取慕课网
前言   Scrapy抓取慕课网免费以及实战课程信息,相关环境列举如下: scrapy v1.5.1 redis psycopg2 (操作并保存数据到PostgreSQL) 数据表   完整的爬虫流程大致是这样的:分析页面结构 -> 确定提取信息 -> 设计相应表结构 -> 编写爬虫脚本 -> 数据保存入库;入库可以选择mongo这样的文档数据库,也可以选择mysql这样的关系型数据库。
1540 0
+关注
sixkery
一个学习python的小白。同名公众号分享学习生活趣事。
文章
问答
视频
相关电子书
更多
Python第五讲——关于爬虫如何做js逆向的思路
立即下载
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载