1. 程式人生 > >Python爬取淘寶店鋪和評論

Python爬取淘寶店鋪和評論

adg 測試工具 .exe .html bar lis 界面 參數 bdr

1 安裝開發需要的一些庫

(1) 安裝mysql 的驅動:在Windows上按win+r輸入cmd打開命令行,輸入命令pip install pymysql,回車即可。

(2) 安裝自動化測試的驅動selenium:在命令行中輸入pip install selenium回車。

(3) 安裝標簽解析庫pyquery: 在命令行中輸入pip install pyquery回車。

(4) Anaconda指的是一個開源的Python發行版本,其包含了conda、Python等180多個科學包及其依賴項,下載anaconda,安裝後配置環境變量,在path中添加E:\Anaconda3\anaconda\Library\bin,重啟電腦使環境變量生效,安裝jieba庫,在命令行中輸入pip install jieba回車。

(5) 下載ChromeDriver,官方網址為:http://chromedriver.storage.googleapis.com/

index.html,並將chromedriver.exe放在Python安裝目錄的Scripts文件夾下。

2.實現

2.1 搜索模塊

搜索功能即一個數據框和一個搜索按鈕組成,點擊搜索之後會跳轉到顯示框的界面,之後點擊爬取數據可以在淘寶網站中對該商品進行搜索,並且爬取相關店鋪的信息,並儲存到數據庫中。

界面顯示用到Tkinter庫,Tkinter 是 Python 的標準 GUI 庫。Python 使用 Tkinter 可以快速的創建 GUI 應用程序。

搜索主要用到selenium,也就是自動化測試工具,測試中根據pyquery中的提供的方法,在得到網頁源碼的情況下,根據HTML中的標簽找到輸入框,搜索按鈕和翻頁的按鈕,模擬人工輸入和點擊,實現自動化控制,最後根據標簽提取出相應的信息插入數據庫中。

因為每個網站因網速的的問題都有響應時間,用WebDriverWait(driver,50)設置響應時間為50s,也就是響應超過50s便出現異常。提取數據時我用的是find_element_by_css_selector()方法,也就是標簽選擇器,可以定位到相應的區域。

Python連接數據庫用到pymysql,PyMySQL 是在 Python3.x 版本中用於連接 MySQL 服務器的一個庫。當得到標題,店鋪名稱,地點,購買人數,店鋪鏈接時,以“|”分割拼接成字符串,作為參數傳遞給insert_data()方法,插入到數據庫中。因為可能會有異常,所以放到try塊中。

爬取數據的實現主要是用到了Pyquery、selenium庫,以下代碼主要實現了對淘寶的檢索、翻頁和對數據的提取。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 # 設置網站最大響應時間 wait=WebDriverWait(driver,50) class TaoBaoSearch: # 初始化,默認搜索為None,創建數據庫連接 def __init__(self,search=None): self.name=search self.mysql=to.Data_oper() # 對淘寶網的搜索 def search(self): # 設置源網站,這裏設置淘寶網站為源網站 driver.get("https://www.taobao.com/")#J_TSearchForm > div.search-button > button # “q”為淘寶首頁輸入框的標簽,這裏定位到該輸入框,並設置要搜索商品的名字 imput=driver.find_element_by_id("q") imput.send_keys(self.name) # wait.until()該方法的作用是加載出來搜索結果總頁數之後開始往下執行 pageText=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,"#mainsrp-pager > div > div > div > div.total"))) total=re.search("\d+",pageText.text) # 該方法返回搜索結果的總頁數 return total.group(0) # 提取出相應的數據 def parseHtml(self): html=driver.page_source#獲取網頁源代碼 doc=qp(html) # 得到到class為m-itemlist下面的class是.items .item的div iteams=doc(".m-itemlist .items .item").items() # 根據標簽選擇器提取出需要的數據 for item in iteams: # src=item(".pic .img").attr("src") src=item(".row .J_ClickStat").attr("href") # 該店鋪的鏈接 person=item(".row .deal-cnt").text() #購買該商品的人數 title=item(".row .J_ClickStat").text().split("\n") # 標題 shop=item(".row .shopname").text() # 商品 location=item(".row .location").text() # 地區 # 將提取到的數據放到數組中保存起來 data=[] data.append(str(title[0].strip())) data.append(str(shop.strip())) data.append(str(location.strip())) # 剔除無用字 data.append(str(person[:-3].strip())) data.append(str(src).strip()) # 調用mysql.insert_data()方法將提取到的數據插入到數據庫中 self.mysql.insert_data(data) # 對網頁進行翻頁的方法 def nextpage(self,pagenumber): # 定位到翻頁的按鈕前的輸入框,也就是對其進行跳轉 pageInput=driver.find_element_by_css_selector("#mainsrp-pager > div > div > div > div.form > input") pageInput.clear() pageInput.send_keys(pagenumber) # 定位到跳轉按鈕,對其進行翻頁 pageButton=driver.find_element_by_css_selector("#mainsrp-pager > div > div > div > div.form > span.btn.J_Submit") pageButton.click() wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR,"#mainsrp-pager > div > div > div > ul > li.item.active > span"),str(pagenumber))) self.parseHtml() # 定義主函數,調用上面的的方法 def main(self): total=int(self.search()) for i in range(2,total): self.nextpage(i) self.mysql.close()

  

2.2 顯示模塊

當點擊搜索之後,考慮到可能搜索的商品會有本地儲存,所以沒有對其直接搜索,而是在顯示框中增加了一個爬取數據的按鈕,該按鈕即對商品進行搜索,而本地數據就是對數據庫的data表進行查詢,並將數據顯示到界面上來。排序是對本地數據按購買人數進行排序,並顯示在文本框中,在顯示行數後面輸入數字後,可以控制文本框的顯示條數,默認顯示10條。一鍵刪除即把data表中的數據清空。

本地數據:對數據庫中的data表進行查詢,並將信息顯示到文本框中,其中每條數據中間以“——”分開,每個字段之間以“|”分隔,因為考慮到店鋪名稱或是標題太長而不整齊,所以每個字段顯示10個字符。

排序:當點擊排序之後,會查詢出數據庫中每條數據的購買人數和店鋪名稱,並且以“,”分割拼接成字符串,設置一個元組(即數組性質),並根據用戶輸入的顯示行數,控制元組的長度,具體實現:根據從數據庫中得到的數據,每條每條的讀取,當讀取條數達到用戶輸入的顯示行數的值,對元組中的數據用sort(reverse=True)對其進行從大到小排序:原理是:因購買人數一個月不超過一百萬,所以得到的購買人數的最大長度為6位,這樣,當每次讀取的購買人數的長度不夠6位時,在其前面補0,這樣,購買人數的長度都為6,對其拼接的格式為“購買人數,店鋪名稱”,因為拼接後為字符串類型,所以用shot排序時會根據前面的購買人數進行字典序進行排序,進而前n條數據就排好序了,接著,每讀取一條數據就對元組中最後一個數據進行比較,若是大於其數值,就插入到元組中,最後返回元組,這樣,就實現了顯示n條購買人數最多的數據。清除數據:對文本框中的數據進行清空,同時,刪除data表中的數據。

以下代碼是一個排序的算法,其主要作用是在界面上顯示多少行數據,主要思路為:根據用戶輸入的數字創建一個數組,讀取數據庫中得到數據,分離出來購買人數並轉換成int類型,將數據每次添加一個到數組中,當數組的長度等於用戶想要顯示最大行數時,對其數組中的數據從大到小進行排序,接下來,每當讀取一個數據之後,就對數組中最小的那個進行比較,如果比起小,就跳過,否則,對該數據進行插入操作,並刪除之前最小的那個數據,最後數組中保存的就是購買人數最多的前n條數據。

主要代碼如下:

技術分享圖片
#對數據進行排序,data為購買人數
def shot_data(self,data,i=10):    # i為用戶想要顯示的最大行數,默認為10行
    top=[]
    if i>len(data):
        i=len(data)
    for x in data:
        if len(top)<i:     # 控制數組的長度,另其大小等於i
            top.append(x)
            if len(top)==i:
                top.sort(reverse=True)        # 數組內的數據進行排序
        else:
            l=len(top)
            y=len(top)
            t=1
            if x>top[l-1]:    # 判斷其數值是否大於數組內的最小值
                while x>top[l-t] and y>0:    # 控制循環條件
                    t+=1
                    y-=1
                if y!=0:    # y的值若是==0,那麽該數值就是最大值
                    for c in range(1,t):
                        top[l-c]=top[l-c-1]
                    top[l-t+1]=x
                else:
                   for c in range(1,t):
                       top[l-c]=top[l-c-1]
                   top[0]=x
    return top    # 返回裝有最大的前i個數的數組
技術分享圖片

2.3 評論模塊

點擊查看鏈接之後會出現一個搜索框,即根據店鋪名稱搜索出相關的連接,點擊查看評論之後可以對其店鋪進行爬取,最後顯示在評論框中。分析就是對評論進行關鍵詞提取,並按權重顯示出前n個詞。點擊查看評論進行自動化測試。

搜索店鋪鏈接:根據用戶輸入的信息對數據庫進行模糊查詢,返回所有的匹配信息。並顯示在文本框中。

爬取評論:首先清空comment表中的數據,根據curselection()方法得到用戶選中的鏈接,接著對該鏈接進行爬取,在進入該店鋪時,會提示需要登錄,這樣會對我們的自動化測試造成一定的阻礙,這裏,我根據pyquery中提供的標簽選擇器,找到關閉按鈕,模擬點擊進行關閉,當進入店鋪後,依舊是先得到該網頁的源代碼,根據標簽選擇器進行相應的操作,爬取到的評論時間,評論和購買物品以“|”拼接成字符串,顯示到文本框的同時插入到數據庫中。

評論分析:jieba是Python的中文分詞組件。當查詢到comment表中所有數據時,將每一條數據拼接成一個字符串,接著用jieba.posseg中的cut()方法,將評論分割成單個詞並標註詞性,用startswith(‘a‘)、startswith(‘v‘)得到形容詞和動詞。最後用jieba.analyse.extract_t

ags(v,topK=10)方法得到動詞、形容詞中權重較大的前10個詞。

以下代碼是對評論進行關鍵詞的提取,用到了jieba庫中的一些方法。

主要代碼如下:

技術分享圖片
def dis_an(self):
# 清空顯示界面
    self.txtMess.delete(1.0,END)
    t=to.Data_oper()
# 得到數據庫中的存儲信息
    test=t.dis_only_discuss()
# 定義字符串adg,v
    adg=""
    v=""
# 對評論進行分割並標註詞性
    word=psg.cut(test)
# w為詞意,f為詞性
    for w,f in word:
    # 判斷詞性是否為形容詞
        if f.startswith(‘a‘):
            print(w)
            adg=adg+","+w
    # 判斷詞性是否為動詞
        elif f.startswith(‘v‘):
            v=v+","+w
    # 根據該詞的權重提取出前5個詞
tags=jieba.analyse.extract_tags(adg,topK=5)
    tags1=jieba.analyse.extract_tags(v,topK=5)

Python爬取淘寶店鋪和評論