基於python爬蟲技術對於淘寶的資料分析的設計與實現

咎如杏咡發表於2023-05-11

本篇僅在於交流學習

本文主要介紹透過 selenium 模組和 requests 模組,同時讓機器模擬人在瀏覽器上的行為,登入指定的網站,透過網站內部的搜尋引擎來搜尋自己相應的資訊,從而獲取相應關鍵字的商品資訊,並進而獲取資料,然後透過csv模組將資料儲存到本地庫中,接著在透過pandas、jieba、matplotlib 等模組進行分析,得出資料的特徵。

 

本章對本系統設計的功能性需求和非功能性需求進行了詳細的分析。把系統所需要的模組進行了整理和劃分,明確了各個功能的需求。

 

設計任務:完成一個基於爬蟲的網路頁面和資料分析

 

(1)訪問功能:使用爬蟲進行頁面訪問。

 

(2)查詢功能:運用程式在頁面上進行自動關鍵字查詢。

 

(3)爬取功能:對於頁面上的資訊進行過濾和針對化的爬取。

 

(4)儲存功能:對於資訊進行本地化的儲存,將爬取資料儲存至csv檔案內。

 

(5)資料分析功能:對於本地化資料進行資料分析和資料展示。

 

構建HTTP偽裝

這是針對 Selenium WebDriver ChromeDriver 來設定的一組瀏覽器引數,以在爬取網站時提高程式穩定性和安全性。這些引數的主要作用如下:

1. '--disable-extensions':禁用 Chrome 擴充套件,避免外掛對頁面渲染產生影響。

2. '--disable-blink-features=AutomationControlled':禁用自動控制特性,避免被目標網站檢測到使用了自動化爬蟲。

3. '--no-sandbox':關閉 Chrome 瀏覽器的沙盤機制,提高程式的執行速度。

4. '--disable-dev-shm-usage':禁用 '/dev/shm' 臨時檔案系統,可避免程式因為記憶體不足而崩潰。

5. '--disable-gpu':禁用 GPU 硬體加速,減少程式資源佔用。

6. '--start-maximized':開啟瀏覽器最大化視窗模式,最佳化使用者體驗。

7. 'add_experimental_option('excludeSwitches', ['enable-automation'])':禁用自動化開關,並防止目標網站檢測到 WebDriver 的使用情況。

8. 'add_experimental_option('useAutomationExtension', False)':禁用自動化擴充套件功能,避免被目標網站檢測到使用了自動化爬蟲。

9. '--user-agent':指定瀏覽器的 User-Agent,在請求目標網站時偽裝成一個正常的瀏覽器訪問,避免被目標網站檢測到使用了自動化爬蟲。

10.'chrome_options.add_argument("--proxy-server=http://{}".format(proxy_address))' 這行程式碼可以在使用Selenium自動化測試時配置代理伺服器。具體來說,'chrome_options' chrome瀏覽器的選項物件,'add_argument()' 方法是向該選項物件中新增引數的方法。

其中, '--proxy-server' Chrome瀏覽器的一個引數,用來設定代理伺服器地址。代理伺服器地址一般包括 IP 地址和埠號,這裡的 'proxy_address' 就是一個包含IP地址和埠號的變數。

使用格式化字串 '"{}'".format(proxy_address)' 將代理伺服器地址插入到引數字串中,最終生成一個完整的代理伺服器地址,然後將其作為引數傳遞給 'add_argument()' 方法。

這樣,啟動 Chrome 瀏覽器時,就會按照傳入的代理伺服器地址來進行網路請求,並透過該代理伺服器獲取網頁內容。這在需要匿名爬取資料或測試一些需要使用代理的網站時非常有用。

這些設定是為了在爬取目標網站時提高程式穩定性、安全性和隱蔽性。

 

headers = {
        'User-Agent': '自己的請求頭'
    }
    chrome_options = webdriver.ChromeOptions()
    # 設定ChromeDriver的options引數,以隱藏自動化控制
    chrome_options.add_argument('--disable-extensions')
    chrome_options.add_argument('--disable-blink-features=AutomationControlled')
    chrome_options.add_argument('--no-sandbox')
    chrome_options.add_argument('--disable-dev-shm-usage')
    chrome_options.add_argument('--disable-gpu')
    chrome_options.add_argument('--start-maximized')
    chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])
    chrome_options.add_experimental_option('useAutomationExtension', False)
    chrome_options.add_argument(f'user-agent={headers["User-Agent"]}')

    # 判斷是否使用代理IP
    proxy_address = get_proxy()
    if proxy_address is not None:
        chrome_options.add_argument("--proxy-server=http://{}".format(proxy_address))  # 新增代理IP地址和埠號到ChromeOptions中

    # 建立ChromeDriver物件
    driver = webdriver.Chrome(options=chrome_options)

模擬登入

 

使用 Selenium WebDriver 實現淘寶網站登入的 Python 函式。其主要實現邏輯如下:

 

1. 跳轉到淘寶登入頁面:利用 WebDriver 開啟淘寶網站登入頁面。

 

2. 輸入賬號和密碼:使用 'find_element_by_id' 方法找到對應的元素並輸入對應的賬號和密碼。

 

3. 登入驗證:等待使用者輸入驗證碼,並點選登入按鈕進行驗證。如果登入成功,則返回登入成功的瀏覽器例項,否則列印錯誤資訊並關閉瀏覽器,返回 None。

 

該函式僅作為示例參考,在實際爬蟲開發中需結合目標網站的特定情況進行調整和最佳化。

def login_taobao(driver, username, password):
    # 跳轉到淘寶登陸頁面
    driver.get('https://login.taobao.com/member/login.jhtml')
    # 輸入賬號和密碼
    username_input = driver.find_element_by_id('fm-login-id')
    password_input = driver.find_element_by_id('fm-login-password')
    username_input.click()
    username_input.send_keys(username)
    password_input.click()
    password_input.send_keys(password)
    time.sleep(10)
    # 登陸驗證
    try:
        # 等待使用者輸入驗證碼
        time.sleep(20)
        # 點選登陸按鈕
        actions = ActionChains(driver)
        actions.move_to_element(driver.find_element_by_class_name('fm-submit'))
        actions.click().perform()
        print('登入成功')
    except Exception as e:
        print('登入失敗: ', e)
        driver.quit()
        return None
    time.sleep(3)
    return driver

資訊爬取

使用 Selenium WebDriver 實現淘寶網站商品爬取的 Python 函式。主要實現邏輯如下:

1. 透過 'driver.get()' 方法開啟淘寶網站搜尋頁,並使用透過讓程式進行暫停操作逃逸反爬蟲檢測'time.sleep()' 方法等待網頁資料載入完成。

2. 使用 'driver.find_elements_by_xpath()' 方法找到頁面上所有需要爬取的商品元素,遍歷每個元素,並使用 'find_element_by_xpath()' 方法定位元素中需要爬取的資訊。

3. 將爬取到的資料儲存為字典格式,並新增到 data 列表中。

4. 如果在遍歷過程中出現異常情況,將錯誤資訊列印到控制檯。

5. 列印當前已完成的頁面數。

 

def crawl_taobao(driver, keyword, pages):
    data = []
    for i in range(1, pages+1):   # 爬取相應頁面的商品資訊
        url = 'https://s.taobao.com/search?q={}&s={}'.format(keyword, (i-1)*44)
        driver.get(url)
        time.sleep(5)
        products = driver.find_elements_by_xpath('//div[@class="items"][1]/div[contains(@class, "item")]')
        for product in products:
            try:
                # 爬取商品名稱、價格、地點、店鋪和銷量等資訊
                title = product.find_element_by_xpath(".//div[@class='row row-2 title']/a")
                price = product.find_element_by_xpath('.//div[@class="price g_price g_price-highlight"]/strong')
                location = product.find_element_by_xpath('.//div[@class="location"]')
                shop = product.find_element_by_xpath('.//div[@class="shop"]/a/span[2]')
                sales = product.find_element_by_xpath('.//div[@class="deal-cnt"]')
                data.append({'Title': title.text.strip(),
                             'Price': float(price.text.strip()),
                             'Location': location.text.strip().replace(' ', ''),
                             'Shop': shop.text.strip(),
                             'Sales': sales.text.strip()})
            except Exception as e:
                print('Error:', e)
        print('已完成第{}頁'.format(i))
    # 將資料儲存為CSV檔案
    df = pd.DataFrame(data)
    with open(keyword + '.csv', 'w', encoding='utf-8-sig', newline='') as f:
        writer = csv.writer(f, quoting=csv.QUOTE_ALL)
        writer.writerow(['Title', 'Price', 'Location', 'Shop', 'Sales'])
        for item in data:
            writer.writerow([item['Title'].replace('"', '""'), item['Price'], item['Location'].replace('"', '""'),
                             item['Shop'].replace('"', '""'), item['Sales']])
    return df

 

  

1. 使用 Pandas 庫的 'DataFrame()' 方法,將爬取到的商品資料 'data' 轉換為 DataFrame 格式。

2. 使用 Python CSV 庫開啟一個新的 CSV 檔案,將資料按照指定格式按行寫入檔案中。

3. DataFrame 格式的資料返回供後續使用。

 

資料分析

 

1. 使用 Pandas 庫的 'mean()''min()' 'max()' 方法,分別計算該 DataFrame 中的價格均值、最低價和最高價,並將結果輸出到控制檯。

 

2. 使用 Matplotlib 庫的 'hist()' 方法,繪製商品價格的直方圖,其中 bins 參數列示劃分價格區間的個數,range 參數列示價格區間的範圍。

 

3. 使用 Matplotlib 庫的 'boxplot()' 方法,繪製商品價格的箱線圖,用於展示價格分佈的離散程度,其中 yticks 引數可以調整箱線圖的 y 軸標籤方向。

 

4. 使用 Matplotlib 庫的 'scatter()' 方法,繪製商品價格和銷量的散點圖,用於展示兩者之間的相關性。

 

5. 使用 Seaborn 庫的 'barplot()' 方法,繪製商品價格的柱形圖,其中使用 'pd.cut()' 方法對價格資料進行分組,並可以指定分組區間,以便更好地展示價格分佈情況。

生成詞雲圖

 

1. 將所有的地區名稱透過空格拼接成一個字串,並使用 jieba 庫的 'lcut()' 方法對字串進行分詞。

 

2. 建立 WordCloud 物件,並指定一些引數,例如背景顏色、字型檔案路徑和停用詞列表等。

 

3. 呼叫 WordCloud 物件的 'generate()' 方法,根據輸入的文字生成詞雲圖。

 

4. 使用 Matplotlib 庫的 'imshow()' 方法,顯示生成的詞雲圖,並使用 'axis()' 方法隱藏座標軸。

 

# 定義函式分析商品價格
def analyze_price(df):
    # 統計均價、最低價和最高價,並顯示到控制檯
    avg_price = round(df['Price'].mean(), 2)
    min_price = df['Price'].min()
    max_price = df['Price'].max()
    print('均價{}元,最低價{}元,最高價{}元'.format(avg_price, min_price, max_price))

    # 繪製商品價格的直方圖
    plt.hist(df['Price'], bins=20, range=(0, 2000))
    plt.xlabel('價格', fontsize=14)
    plt.ylabel('數量', fontsize=14)
    plt.xticks(rotation=45)
    plt.yticks(fontsize=14)
    plt.title('商品價格分佈直方圖')
    plt.show()

    # 繪製商品價格的箱線圖
    plt.boxplot(df['Price'])
    plt.ylabel('價格', fontsize=14)
    plt.yticks(fontsize=14, rotation=-45)
    plt.title('商品價格分佈箱線圖')
    plt.show()

    # 繪製商品價格和銷量的散點圖
    plt.scatter(df['Price'], df['Sales'], s=50, alpha=0.7, c='b', marker='o')
    plt.xlabel('價格')
    plt.ylabel('銷量')
    plt.title('商品價格與銷量關係散點圖')
    plt.grid(True)
    plt.show()

    # 繪製商品價格的柱形圖
    df_price = df.groupby(pd.cut(df['Price'], bins=[0, 100, 200, 300, 500, 800, 1200, 2000]))['Price'].count()
    plt.figure(figsize=(8, 6))
    sns.barplot(x=df_price.index.astype(str), y=df_price.values, color='coral')
    plt.xlabel('價格區間', fontsize=14)
    plt.ylabel('數量', fontsize=14)
    plt.xticks(rotation=45)
    plt.yticks(fontsize=14)
    plt.title('商品價格分佈柱形圖')
    plt.show()

# 定義函式生成地區詞雲圖
def make_location_wordcloud(df):
    # 合併所有地區資料為一個字串
    location_str = ' '.join(df['Location'])
    # 使用jieba庫對字串進行分詞
    words = jieba.lcut(location_str)
    new_location_str = ' '.join(words)
    # 停用詞列表
    stopwords = ['市', '省', '自治區', '特別行政區']
    # 建立WordCloud物件
    wc = WordCloud(background_color='white', font_path='msyh.ttc', stopwords=stopwords)
    # 生成詞雲圖
    wc.generate(new_location_str)
    # 顯示詞雲圖
    plt.imshow(wc, interpolation='bilinear')
    plt.axis('off')
    plt.show()

 

  

新增代理地址判斷功能及有關於輸入資料判斷出錯處理

資料判斷

 

 

1. 使用 Python 'while' 迴圈,一直等待使用者輸入,直到輸入格式正確為止。

 

2. 使用內建函式 'int()' 將使用者輸入的字串轉換為整數型別。

 

3. 如果輸入內容不能正常轉換為整數,則捕獲 'ValueError' 異常,並提示使用者重新輸入。

 

4. 如果使用者輸入正確,將輸入的整數作為函式返回值。

代理IP判斷

 

1. 使用 'input()' 函式讓使用者選擇是否使用代理 IP,當輸入不為 'Y' 或者 'N' 時,透過 'while' 迴圈不斷重新提示輸入直至正確。

2. 如果使用者選擇使用代理 IP,透過 'input()' 函式獲取代理 IP,如果輸入不符合規範,透過多層巢狀的 'try...except...' 分別對輸入的 IP 和埠號進行校驗,分別檢查其是否在規定的範圍內和是否符合 IPv4 地址格式。

3. 如有輸入不符合規範,透過 'print()' 函式及 'input()' 函式讓使用者選擇操作。

4. 如果使用者選擇重新輸入代理 IP,則透過 'continue' 關鍵字實現迴圈,反之返回 'None'

 

 

 

 

# 定義函式輸入數字是否有誤
def get_pages():
    while True:
        try:
            pages = int(input('請輸入要爬取的頁碼數:'))
            break
        except ValueError:
            print("請輸入數字!")
    return pages

# 定義函式是否使用代理IP
def get_proxy():
    use_proxy = input('是否需要使用代理IP?(Y/N):').upper()
    # 判斷輸入是否有誤
    while use_proxy not in ['Y', 'N']:  # 如果輸入的字元不是Y或N,則重新提示輸入
        print('請輸入正確的(Y/N)')
        use_proxy = input('是否需要使用代理IP?(Y/N):').upper()
    if use_proxy == 'Y':
        proxy_address = input('請輸入代理IP地址和埠號(例如:ip:port):')
        # 判斷代理IP是否正確
        while True:
            try:
                ip, port = proxy_address.split(':')  # 提取IP地址和埠號
                if not (0 < int(port) < 65536):  # 埠號不在合法範圍內
                    print('代理IP地址和埠號輸入有誤,請選擇操作:')
                    print('1. 重新輸入代理IP地址和埠號')
                    print('2. 不使用代理IP')
                    choice = input('請選擇操作(1/2):')
                    while choice not in ['1', '2']:
                        print('請輸入正確的選項:')
                        choice = input('請選擇操作(1/2):')
                    if choice == '1':
                        proxy_address = input('請輸入代理IP地址和埠號(例如:ip:port):')
                        continue
                    else:
                        return None
                parts = ip.split('.')
                if len(parts) != 4 or not all(0 <= int(part) < 256 for part in parts):  # IP地址格式不正確
                    print('代理IP地址和埠號輸入有誤,請選擇操作:')
                    print('1. 重新輸入代理IP地址和埠號')
                    print('2. 不使用代理IP')
                    choice = input('請選擇操作(1/2):')
                    while choice not in ['1', '2']:
                        print('請輸入正確的選項:')
                        choice = input('請選擇操作(1/2):')
                    if choice == '1':
                        proxy_address = input('請輸入代理IP地址和埠號(例如:ip:port):')
                        continue
                    else:
                        return None
                break  # 輸入合法,跳出迴圈
            except Exception:
                print('代理IP地址和埠號輸入有誤,請選擇操作:')
                print('1. 重新輸入代理IP地址和埠號')
                print('2. 不使用代理IP')
                choice = input('請選擇操作(1/2):')
                while choice not in ['1', '2']:
                    print('請輸入正確的選項:')
                    choice = input('請選擇操作(1/2):')
                if choice == '1':
                    proxy_address = input('請輸入代理IP地址和埠號(例如:ip:port):')
                else:
                    return None
        return proxy_address
    else:
        print('不使用代理IP。')  # 直接提示使用者不使用代理IP
        return None

 

執行結果

 

 

 

 

 

 

 

 

 完整程式碼

 

import csv
import time
from selenium.webdriver.common.proxy import Proxy, ProxyType
import jieba
import matplotlib as mpl
import matplotlib.pyplot as plt
import pandas as pd
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from wordcloud import WordCloud
import seaborn as sns

mpl.rcParams['font.family'] = 'SimSun'
mpl.rcParams['font.size'] = 14

# 定義函式模擬登陸淘寶
def login_taobao(driver, username, password):
    # 跳轉到淘寶登陸頁面
    driver.get('https://login.taobao.com/member/login.jhtml')
    # 輸入賬號和密碼
    username_input = driver.find_element_by_id('fm-login-id')
    password_input = driver.find_element_by_id('fm-login-password')
    username_input.click()
    username_input.send_keys(username)
    password_input.click()
    password_input.send_keys(password)
    time.sleep(10)
    # 登陸驗證
    try:
        # 等待使用者輸入驗證碼
        time.sleep(20)
        # 點選登陸按鈕
        actions = ActionChains(driver)
        actions.move_to_element(driver.find_element_by_class_name('fm-submit'))
        actions.click().perform()
        print('登入成功')
    except Exception as e:
        print('登入失敗: ', e)
        driver.quit()
        return None
    time.sleep(3)
    return driver

# 定義函式爬取淘寶商品資訊
def crawl_taobao(driver, keyword, pages):
    data = []
    for i in range(1, pages+1):   # 爬取相應頁面的商品資訊
        url = 'https://s.taobao.com/search?q={}&s={}'.format(keyword, (i-1)*44)
        driver.get(url)
        time.sleep(5)
        products = driver.find_elements_by_xpath('//div[@class="items"][1]/div[contains(@class, "item")]')
        for product in products:
            try:
                # 爬取商品名稱、價格、地點、店鋪和銷量等資訊
                title = product.find_element_by_xpath(".//div[@class='row row-2 title']/a")
                price = product.find_element_by_xpath('.//div[@class="price g_price g_price-highlight"]/strong')
                location = product.find_element_by_xpath('.//div[@class="location"]')
                shop = product.find_element_by_xpath('.//div[@class="shop"]/a/span[2]')
                sales = product.find_element_by_xpath('.//div[@class="deal-cnt"]')
                data.append({'Title': title.text.strip(),
                             'Price': float(price.text.strip()),
                             'Location': location.text.strip().replace(' ', ''),
                             'Shop': shop.text.strip(),
                             'Sales': sales.text.strip()})
            except Exception as e:
                print('Error:', e)
        print('已完成第{}頁'.format(i))
    # 將資料儲存為CSV檔案
    df = pd.DataFrame(data)
    with open(keyword + '.csv', 'w', encoding='utf-8-sig', newline='') as f:
        writer = csv.writer(f, quoting=csv.QUOTE_ALL)
        writer.writerow(['Title', 'Price', 'Location', 'Shop', 'Sales'])
        for item in data:
            writer.writerow([item['Title'].replace('"', '""'), item['Price'], item['Location'].replace('"', '""'),
                             item['Shop'].replace('"', '""'), item['Sales']])
    return df

# 定義函式分析商品價格
def analyze_price(df):
    # 統計均價、最低價和最高價,並顯示到控制檯
    avg_price = round(df['Price'].mean(), 2)
    min_price = df['Price'].min()
    max_price = df['Price'].max()
    print('均價{}元,最低價{}元,最高價{}元'.format(avg_price, min_price, max_price))

    # 繪製商品價格的直方圖
    plt.hist(df['Price'], bins=20, range=(0, 2000))
    plt.xlabel('價格', fontsize=14)
    plt.ylabel('數量', fontsize=14)
    plt.xticks(rotation=45)
    plt.yticks(fontsize=14)
    plt.title('商品價格分佈直方圖')
    plt.show()

    # 繪製商品價格的箱線圖
    plt.boxplot(df['Price'])
    plt.ylabel('價格', fontsize=14)
    plt.yticks(fontsize=14, rotation=-45)
    plt.title('商品價格分佈箱線圖')
    plt.show()

    # 繪製商品價格和銷量的散點圖
    plt.scatter(df['Price'], df['Sales'], s=50, alpha=0.7, c='b', marker='o')
    plt.xlabel('價格')
    plt.ylabel('銷量')
    plt.title('商品價格與銷量關係散點圖')
    plt.grid(True)
    plt.show()

    # 繪製商品價格的柱形圖
    df_price = df.groupby(pd.cut(df['Price'], bins=[0, 100, 200, 300, 500, 800, 1200, 2000]))['Price'].count()
    plt.figure(figsize=(8, 6))
    sns.barplot(x=df_price.index.astype(str), y=df_price.values, color='coral')
    plt.xlabel('價格區間', fontsize=14)
    plt.ylabel('數量', fontsize=14)
    plt.xticks(rotation=45)
    plt.yticks(fontsize=14)
    plt.title('商品價格分佈柱形圖')
    plt.show()

# 定義函式生成地區詞雲圖
def make_location_wordcloud(df):
    # 合併所有地區資料為一個字串
    location_str = ' '.join(df['Location'])
    # 使用jieba庫對字串進行分詞
    words = jieba.lcut(location_str)
    new_location_str = ' '.join(words)
    # 停用詞列表
    stopwords = ['市', '省', '自治區', '特別行政區']
    # 建立WordCloud物件
    wc = WordCloud(background_color='white', font_path='msyh.ttc', stopwords=stopwords)
    # 生成詞雲圖
    wc.generate(new_location_str)
    # 顯示詞雲圖
    plt.imshow(wc, interpolation='bilinear')
    plt.axis('off')
    plt.show()

# 定義函式輸入數字是否有誤
def get_pages():
    while True:
        try:
            pages = int(input('請輸入要爬取的頁碼數:'))
            break
        except ValueError:
            print("請輸入數字!")
    return pages

# 定義函式是否使用代理IP
def get_proxy():
    use_proxy = input('是否需要使用代理IP?(Y/N):').upper()
    # 判斷輸入是否有誤
    while use_proxy not in ['Y', 'N']:  # 如果輸入的字元不是Y或N,則重新提示輸入
        print('請輸入正確的(Y/N)')
        use_proxy = input('是否需要使用代理IP?(Y/N):').upper()
    if use_proxy == 'Y':
        proxy_address = input('請輸入代理IP地址和埠號(例如:ip:port):')
        # 判斷代理IP是否正確
        while True:
            try:
                ip, port = proxy_address.split(':')  # 提取IP地址和埠號
                if not (0 < int(port) < 65536):  # 埠號不在合法範圍內
                    print('代理IP地址和埠號輸入有誤,請選擇操作:')
                    print('1. 重新輸入代理IP地址和埠號')
                    print('2. 不使用代理IP')
                    choice = input('請選擇操作(1/2):')
                    while choice not in ['1', '2']:
                        print('請輸入正確的選項:')
                        choice = input('請選擇操作(1/2):')
                    if choice == '1':
                        proxy_address = input('請輸入代理IP地址和埠號(例如:ip:port):')
                        continue
                    else:
                        return None
                parts = ip.split('.')
                if len(parts) != 4 or not all(0 <= int(part) < 256 for part in parts):  # IP地址格式不正確
                    print('代理IP地址和埠號輸入有誤,請選擇操作:')
                    print('1. 重新輸入代理IP地址和埠號')
                    print('2. 不使用代理IP')
                    choice = input('請選擇操作(1/2):')
                    while choice not in ['1', '2']:
                        print('請輸入正確的選項:')
                        choice = input('請選擇操作(1/2):')
                    if choice == '1':
                        proxy_address = input('請輸入代理IP地址和埠號(例如:ip:port):')
                        continue
                    else:
                        return None
                break  # 輸入合法,跳出迴圈
            except Exception:
                print('代理IP地址和埠號輸入有誤,請選擇操作:')
                print('1. 重新輸入代理IP地址和埠號')
                print('2. 不使用代理IP')
                choice = input('請選擇操作(1/2):')
                while choice not in ['1', '2']:
                    print('請輸入正確的選項:')
                    choice = input('請選擇操作(1/2):')
                if choice == '1':
                    proxy_address = input('請輸入代理IP地址和埠號(例如:ip:port):')
                else:
                    return None
        return proxy_address
    else:
        print('不使用代理IP。')  # 直接提示使用者不使用代理IP
        return None

# 建立總方法呼叫函式
def main():
    # 使用者輸入賬號、密碼和要搜尋的商品關鍵字
    username = input('請輸入淘寶賬號:')
    password = input('請輸入淘寶密碼:')
    keyword = input('請輸入要搜尋的商品關鍵字:')

    # 輸入數字是否有誤
    pages = get_pages()

    # 設定請求頭資訊
    headers = {
        'User-Agent': '自己的請求頭'
    }
    chrome_options = webdriver.ChromeOptions()
    # 設定ChromeDriver的options引數,以隱藏自動化控制
    chrome_options.add_argument('--disable-extensions')
    chrome_options.add_argument('--disable-blink-features=AutomationControlled')
    chrome_options.add_argument('--no-sandbox')
    chrome_options.add_argument('--disable-dev-shm-usage')
    chrome_options.add_argument('--disable-gpu')
    chrome_options.add_argument('--start-maximized')
    chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])
    chrome_options.add_experimental_option('useAutomationExtension', False)
    chrome_options.add_argument(f'user-agent={headers["User-Agent"]}')

    # 判斷是否使用代理IP
    proxy_address = get_proxy()
    if proxy_address is not None:
        chrome_options.add_argument("--proxy-server=http://{}".format(proxy_address))  # 新增代理IP地址和埠號到ChromeOptions中

    # 建立ChromeDriver物件
    driver = webdriver.Chrome(options=chrome_options)
    driver = login_taobao(driver, username, password)

    # 如果登陸成功,進行商品資訊爬取、價格分析和詞雲製作
    if driver is not None:
        df = crawl_taobao(driver, keyword, pages)
        # 如果爬取到的資料不為空,才進行價格分析和詞雲製作
        if not df.empty:
            analyze_price(df)
            make_location_wordcloud(df)

    # 關閉瀏覽器
    driver.quit()

if __name__ == '__main__':
    main()

 

 結尾

這是根據模擬登陸進行淘寶網內部商品的資料獲取和分析製作的一個小工具,考慮到淘寶網內部進行反爬蟲技術強面對滑塊登入驗證還暫且無法做到,但是進行試驗還是可以,在使用時需配合ChromeDriver使用,透過與Selenium Webdriver一起使用,來自動化執行各種Web操作。

 

相關文章