1. 程式人生 > 實用技巧 >Python爬蟲怕封IP?這個方法讓你沒有顧慮!

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 爬蟲
(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)
以上內容無用,為本篇部落格被搜尋引擎抓取使用