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

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 上回说到设置随机 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 被封。同时不要让网站的压力太大。这样才能共存。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
Python 数据采集
scrapy突破反爬的几种方式(三)
一些小的技巧配置,让我们的爬虫被识别的概率降低。 cookies 的禁用 在settings.py 文件中有一个参数是: COOKIES_ENABLED = False 默认情况下是禁用的,request 就不会把 cookies 带进去。
1206 0
|
18天前
|
数据采集 存储 JSON
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第27天】本文介绍了Python网络爬虫Scrapy框架的实战应用与技巧。首先讲解了如何创建Scrapy项目、定义爬虫、处理JSON响应、设置User-Agent和代理,以及存储爬取的数据。通过具体示例,帮助读者掌握Scrapy的核心功能和使用方法,提升数据采集效率。
60 6
|
1月前
|
数据采集 中间件 开发者
Scrapy爬虫框架-自定义中间件
Scrapy爬虫框架-自定义中间件
|
1月前
|
数据采集 中间件 Python
Scrapy爬虫框架-通过Cookies模拟自动登录
Scrapy爬虫框架-通过Cookies模拟自动登录
|
19天前
|
数据采集 前端开发 中间件
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第26天】Python是一种强大的编程语言,在数据抓取和网络爬虫领域应用广泛。Scrapy作为高效灵活的爬虫框架,为开发者提供了强大的工具集。本文通过实战案例,详细解析Scrapy框架的应用与技巧,并附上示例代码。文章介绍了Scrapy的基本概念、创建项目、编写简单爬虫、高级特性和技巧等内容。
41 4
|
17天前
|
数据采集 中间件 API
在Scrapy爬虫中应用Crawlera进行反爬虫策略
在Scrapy爬虫中应用Crawlera进行反爬虫策略
|
6月前
|
数据采集 中间件 Python
Scrapy爬虫:利用代理服务器爬取热门网站数据
Scrapy爬虫:利用代理服务器爬取热门网站数据
|
1月前
|
数据采集 中间件 数据挖掘
Scrapy 爬虫框架(一)
Scrapy 爬虫框架(一)
|
1月前
|
数据采集 XML 前端开发
Scrapy 爬虫框架(二)
Scrapy 爬虫框架(二)
|
3月前
|
数据采集 中间件 调度
Scrapy 爬虫框架的基本使用
Scrapy 爬虫框架的基本使用