zoukankan      html  css  js  c++  java
  • Python爬虫怕封IP?这个方法让你没有顾虑!

    【导语】:做爬虫的时候,难免会快速多次地访问某个网站,触发网站的反爬虫机制,就会“封IP”。解决方法之一就是用代理池,本文就向大家介绍使用Mysql维护一个代理池的方法。

    1. 配置PyCharm

      为了方便写SQL代码及实时关注数据库的信息,我们先配置一下PyCharm。

      找到PyCharm右边栏的Database,点击它,然后它的界面会弹出来,点击+号,选择数据库。

    如图示操作,找到我们的小鲸鱼MySQL,点击进入。

    通过这个界面就可以配置MySQL了,这里有几个填写的我已经作了标注,简单介绍一下:

    Name: 本次的配置的名字,这里我填的是spider,也可以使用默认名@localhost。

    Host: 数据库的IP地址,因为我的MySQL在本地,所以这里我填的就是localhost。

    User: 数据库的用户名。

    Password: 数据库的密码。

    Database: 数据库的名字,我这里提前建了一个名为spider的数据库。

    URL: 这里我们在后面加上?serverTimezone=UTC,否则的话等会儿我们连接时会出现Server returns invalid timezone. Go to ‘Advanced’ tab and set‘serverTimezone’ property manually.错误,或者按照错误提示,去Advanced选项配置一下Advanced。

    配置完后就点击Test Connection按钮,如果提示缺少驱动文件,直接在弹出的对话框点击下载即可,不出意外的话,就会在下面出现连接成功的信息。

    插入数据后,按图示操作刷新一下,然后双击数据表,就可以看到数据表中的信息了,美滋滋ヾ(@▽@)ノ。

    注意:如果你是打算找python高薪工作的话。我建议你多写点真实的企业项目积累经验。不然工作都找不到,当然很多人没进过企业,怎么会存在项目经验呢? 所以你得多找找企业项目实战多练习下撒。如果你很懒不想找,也可以进我的Python交流圈:1156465813。群文件里面有我之前在做开发写过的一些真实企业项目案例。你可以拿去学习,不懂都可以在裙里找我,有空会耐心给你解答下。

    2. 函数介绍

      这里我们通过pymysql库来操作MySQL数据库,我的数据库版本是8.0.16,还是去年安装的,这里不再叙述其安装步骤了,问问度娘。


      维护我们代理IP池的大致流程就是:先建立一个数据表ipproxy,包含有ip字段、score字段,因为有些IP有时候可以用,有时候不可以,所以这里对每个要存入数据库的IP设置一个分数,我这里设置的最高分是5,也就是质量最高。如果我们在使用过程中发现IP不能用了,就将其分数减1;如果可以用,且分数小于5,就加1,然后定期清理分数为0的IP。

    3. 代码实现

    这里只贴出了增加的数据库操作代码及修改后的IP测试代码。

    import pymysql
    import requests
    from bs4 import BeautifulSoup
    import pickle
    import aiohttp
    import asyncio
    import time
    import random
    
    
    async def test_newip(ip_, url, ip_ok):
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                                 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'}
        conn = aiohttp.TCPConnector(verify_ssl=False)
        async with aiohttp.ClientSession(connector=conn) as session:
            print('正在测试ip: ' + ip_)
            try:
                proxy_ip = 'http://' + ip_
                async with session.get(url=url, headers=headers, proxy=proxy_ip, timeout=15) as response:
                    if response.status == 200:
                        print('代理可用: ' + ip_)
                        ip_ok.append((ip_, 5))
                    else:
                        print('请求响应码不合法 ' + ip_)
            except:
                ip_ok.append((ip_, 4))
                print('代理请求失败', ip_)
    
    
    async def test_mysqlip(ip_, url, ip_ok):
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                                 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'}
        conn = aiohttp.TCPConnector(verify_ssl=False)
        async with aiohttp.ClientSession(connector=conn) as session:
            print('正在测试ip: ' + ip_[0])
            try:
                proxy_ip = 'http://' + ip_[0]
                async with session.get(url=url, headers=headers, proxy=proxy_ip, timeout=15) as response:
                    if response.status == 200:
                        print('ip可用: ' + ip_[0])
                        new_score = 5 if ip_[1] == 5 else ip_[1] + 1
                        ip_ok.append((ip_[0], new_score))
                    else:
                        print('请求响应码不合法 ' + ip_[0])
            except:
                new_score = 0 if ip_[1] == 0 else ip_[1] - 1
                ip_ok.append((ip_[0], new_score))
                print('代理请求失败', ip_[0])
    
    
    def get_mysqlip():
        db = pymysql.connect(host='localhost', port=3306, user='用户名', password='密码',
                             database='数据库名', charset='utf8')
        cursor = db.cursor()
        sql = 'select ip, score from ipproxy'
        try:
            cursor.execute(sql)
            mysql_ip = list(cursor.fetchall())
            return mysql_ip
        except Exception as err:
            print('查询错误!!!')
            print(err)
    
    
    def update_ipscore(ip_list):
        db = pymysql.connect(host='localhost', port=3306, user='用户名', password='密码',
                             database='数据库名', charset='utf8')
        cursor = db.cursor()
        for ip_ in ip_list:
            sql = 'update ipproxy set score=%s where ip=%s'
            cursor.execute(sql, (ip_[1], ip_[0]))
            db.commit()
        cursor.close()
        db.close()
    
    
    def delete_ip():
        db = pymysql.connect(host='localhost', port=3306, user='用户名', password='密码',
                             database='数据库名', charset='utf8')
        cursor = db.cursor()
        sql = 'delete from ipproxy where score=0'
        try:
            cursor.execute(sql)
        except Exception as err:
            print('删除错误!!!')
            print(err)
        db.commit()
        cursor.close()
        db.close()
    
    
    def delete_ideticalip():
        db = pymysql.connect(host='localhost', port=3306, user='用户名', password='密码',
                             database='数据库名', charset='utf8')
        cursor = db.cursor()
        sql = 'delete from ipproxy where ip in (select ip  from (select ip from ipproxy group by ip having count(*)>1) s1)' 
              'and id not in (select id from (select id from ipproxy group by ip having count(*)>1) s2)'
        try:
            cursor.execute(sql)
        except Exception as err:
            print('删除错误!!!')
            print(err)
        db.commit()
        cursor.close()
        db.close()
    
    
    def insert_ip(ip_list):
        # 新爬取的ip直接插入数据库
        db = pymysql.connect(host='localhost', port=3306, user='用户名', password='密码',
                             database='数据库名', charset='utf8')
        cursor = db.cursor()
        sql = 'create table if not exists ipproxy(' 
              'id int not null primary key auto_increment, ' 
              'ip char(21) not null , ' 
              'score int not null ) default charset utf8'
        cursor.execute(sql)
    
        try:
            sql = 'insert into ipproxy (ip, score) values (%s, %s)'
            cursor.executemany(sql, ip_list)
            # cursor.execute('drop table ipproxy')
        except Exception as err:
            print('插入错误!!!')
            print(err)
        db.commit()
        cursor.close()
        db.close()
    
    
    def insret_mysqlip(urls):
        ip_list1 = get_66ip()
        ip_list2 = get_kaixinip()
        ip_list3 = get_goubanjiaip()
        ip_list = list(set(ip_list1 + ip_list2 + ip_list3))
        print('已做去重处理!')
    
        ip_ok = []
        print('开始测试新爬取的ip: ')
        try:
            loop = asyncio.get_event_loop()
            for i in range(0, len(ip_list), 10):
                proxies_ip = ip_list[i: i + 10]
                tasks = [test_newip(proxy_ip, random.choice(urls), ip_ok) for proxy_ip in proxies_ip]
                loop.run_until_complete(asyncio.wait(tasks))
                time.sleep(3)
        except Exception as err:
            print('发生错误:', err.args)
    
        insert_ip(ip_ok)
        print('数据保存完毕!')
    
    
    def update_mysqlip(urls):
        ip_list = get_mysqlip()
        ip_ok = []
        print('开始测试新爬取的ip: ')
        try:
            loop = asyncio.get_event_loop()
            for i in range(0, len(ip_list), 10):
                proxies_ip = ip_list[i: i + 10]
                tasks = [test_mysqlip(proxy_ip, random.choice(urls), ip_ok) for proxy_ip in proxies_ip]
                loop.run_until_complete(asyncio.wait(tasks))
                time.sleep(3)
        except Exception as err:
            print('发生错误:', err.args)
    
        update_ipscore(ip_ok)
      print('数据更新完毕!')
    
        delete_ip()
        print('已删除score为0的ip!')
    
        delete_ideticalip()
        print('已做去重处理!')
    
    if __name__ == '__main__':
        urls = ['https://blog.csdn.net/qq_42730750/article/details/107868879',
                'https://blog.csdn.net/qq_42730750/article/details/107931738',
                'https://blog.csdn.net/qq_42730750/article/details/107869022',
                'https://blog.csdn.net/qq_42730750/article/details/108016855',
                'https://blog.csdn.net/qq_42730750/article/details/107703589',
                'https://blog.csdn.net/qq_42730750/article/details/107869233',
                'https://blog.csdn.net/qq_42730750/article/details/107869944',
                'https://blog.csdn.net/qq_42730750/article/details/107919690']
    
        insret_mysqlip(urls)
        update_mysqlip(urls)
    

      

    以下内容无用,为本篇博客被搜索引擎抓取使用
    (* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)
    python 是干什么的 零基础学 python 要多久 python 为什么叫爬虫
    python 爬虫菜鸟教程 python 爬虫万能代码 python 爬虫怎么挣钱
    python 基础教程 网络爬虫 python python 爬虫经典例子
    python 爬虫
    (* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)
    以上内容无用,为本篇博客被搜索引擎抓取使用

  • 相关阅读:
    request.json 打印中文乱码解决
    看懂项目代码需要掌握的技能 (java语言)
    jmeter响应断言通过,结果树中却显示红色
    nginx的upstream后端名称居然变成了请求的host了?
    基于QRcode创建和识别二维码的研究
    thinkphp访问mysql中文字段问题
    apache https访问配置
    如何获得bibitem格式的参考文献
    CSharp: Image Matting
    word2vec回顾
  • 原文地址:https://www.cnblogs.com/shuchongzeishuai/p/14034528.html
Copyright © 2011-2022 走看看