[python]利用selenium模擬用戶操作抓取天貓評論數據


准備:

python3.5

安裝selenium包

第一種方法:

cmd里輸pip install selenium,但是經常報錯

第二種方法:

下載安裝包-cmd進入解壓路徑-python setup.py install-報錯permission denied-右鍵安全更改報錯文件夾權限為完全控制-再次安裝成功
unknown error: unable to discover open pages-下載chromedriver放在環境變量目錄下
測試自動打開百度時提示“您使用的是不受支持的命令行標記”-更改chromedriver版本為對應版本即可

安裝包下載地址:https://pypi.python.org/pypi/selenium

chromedriver與chrome版本映射及下載地址:http://blog.csdn.net/huilan_same/article/details/51896672

實現:

selenium基本上就是模擬打開瀏覽器,向下滑動點擊評論tab點擊下一頁等過程。由於selenium只能對顯示在屏幕范圍內的元素操作,所以滾動條操作很重要。

def deal_recommends_infos(url):
    if not url.startswith('http'):
        url = 'https:' + url

    print('開始尋找評論:' + url)
    driver = webdriver.Chrome()
    driver.maximize_window() # 全屏 
    
    timeout = 30
    try:
        driver.get(url)
        WebDriverWait(driver, timeout).until(
            EC.presence_of_element_located((By.ID, "J_TabBarBox"))  # 判斷頁面是否初步加載成功的標記
        )
    except TimeoutException:
        print('寶貝鏈接未加載成功')

    try:
        # 頁面上拉600,看到TabBarBox
        js = "window.scrollTo(0,600)"
        driver.execute_script(js)
    except WebDriverException:
        print('上拉尋找評論區時出現問題')
    time.sleep(2)
    # 點擊累計評論TAB
    driver.find_element_by_xpath('//*[@id="J_TabBar"]/li[2]').click()
    time.sleep(4)
    print('成功點擊累計評論TAB')

    try:
        # rate-grid的正則表達式
        driver.find_element_by_xpath('//*[@id="J_Reviews"]/div/div[6]')
    except NoSuchElementException:
        print('評論信息中元素還未加載')
    print('已經成功加載到評論區信息')
 
    for i in range(2):
        try:

            js = "window.scrollTo(0,2500)"
            driver.execute_script(js)
            time.sleep(2)
            # 點擊下一頁
            driver.find_element_by_css_selector('#J_Reviews > div > div.rate-page > div > a:last-child').click()
        
        except WebDriverException:    
            js = "window.scrollTo(0,3500)"
            driver.execute_script(js)
            time.sleep(2)
            # 點擊下一頁
            driver.find_element_by_css_selector('#J_Reviews > div > div.rate-page > div > a:last-child').click()
        except NoSuchElementException:
            print('找不到翻頁按鈕')
            continue
        print('已成功點擊下一頁')
        soup = BeautifulSoup(driver.page_source, "lxml")
        print(get_recommends_infos(soup))
        
    print('完成該鏈接的評論抓取')

 

要注意的點:

瀏覽器要全屏,缺少這個操作的話很容易出現bug,我猜是因為天貓商城右下角的二維碼妨礙了鼠標點擊。

下拉網頁點擊下一頁時,由於天貓商城每頁的評論長度不是那么確定,設置絕對值容易出現拉不到或者拉過了的情況,要做一個try語句。

target = driver.find_element_by_css_selector('#J_Reviews > div > div.rate-page > div > a:last-child')
driver.execute_script("arguments[0].scrollIntoView();",target) #拖動到可見的元素去

我嘗試用以上代碼來滾動到指定元素可見,但是總報is not clickable at point (1030, 19). Other element would receive the click:查了下是被天貓商城那個手機購買的二維碼擋住了……現在暫時沒有解決方案,只能先拉2500,不夠就再加個1000。

理論上來說

soup = BeautifulSoup(driver.page_source, "lxml")
print(get_recommends_infos(soup))

這兩句應該是放在點擊下一頁之前的,但是不知道為啥這樣就會出現把第一頁抓取兩遍的情況。神tm換下代碼順序就正常了,想不通為什么這樣結果對,我再慢慢研究吧。

#提取評論信息
def get_recommends_infos(s):
    comment = s.find("div",class_="rate-grid")
    comment_data = comment.find_all("tr")
    lst1=[]
    #逐行讀取
    for i in comment_data:
        goodstype_lst=[]
        username_lst=[]
        #comment1為初次評論,comment2為追加評論,reply1為商家初次回復,reply2為商家追加回復,goodstype為商品類型,username為用戶名
        dic={'comment1': '','reply1':'','comment2': '','reply2':'', 'goodstype': goodstype_lst, 'username': username_lst} 
        try:
            content1=i.find('div',class_="tm-rate-premiere").find('div',class_="tm-rate-content")
            dic['comment1']=content1.text
        except:
            content1=i.find('div',class_="tm-rate-content").find('div',class_="tm-rate-fulltxt")
            dic['comment1']=content1.text
        try:
            content2=i.find('div',class_="tm-rate-append").find('div',class_="tm-rate-content")
            dic['comment2']=content2.text
        except:
            dic['comment2']='null'
        
        try:
            reply1=i.find('div',class_="tm-rate-premiere").find('div',class_="tm-rate-reply")
            dic['reply1']=reply1.text
        except:
            try:
                reply2=i.find('div',class_="tm-rate-append").find('div',class_="tm-rate-reply")
                dic['reply1']='null'
            except:
                try:
                    reply1=i.find('div',class_="tm-rate-reply")
                    dic['reply1']=reply1.text
                except:
                    dic['reply1']='null'
        try:
            reply2=i.find('div',class_="tm-rate-append").find('div',class_="tm-rate-reply")
            dic['reply2']=reply2.text
        except:
            dic['reply2']='null'
        goodstype=i.find('div',class_="rate-sku").find_all('p')
        for b in goodstype:
            goodstype_lst.append(b.attrs['title'])
        username=i.find_all('div',class_="rate-user-info")
        for c in username:
            username_lst.append(c.text)
        lst1.append(dic)        
    return lst1

 

要注意的點:

初次評論:如果有追加評論的話div會被分成class=tm-rate-premiere和tm-rate-append兩塊,這兩塊里面又分別有tm-rate-content,沒有追加評論的情況下評論就是tm-rate-content一整塊。因此直接用BeautifulSoup找tm-rate-content是有問題的,可能會找到兩個評論。

追加評論:這個比較好判斷,沒有tm-rate-append的話就沒有追加評論

初次回復:回復情況分為下表6種,其中有初次回復的分為1、2、5共3種,先通過find('div',class_="tm-rate-premiere").find('div',class_="tm-rate-reply")把1選出來了,剩下5種中,把3排除掉,第一個被找到的tm-rate-reply就是初次回復。

序號 追評 初次回復 追評回復
1
2
3
4
5
6

追加回復:通過find('div',class_="tm-rate-append").find('div',class_="tm-rate-reply")把1、3選出來了,剩下的都為null

 參考:

Python利器之使用Selenium模擬用戶操作抓取天貓評論數據 - 知乎專欄

Python爬蟲利器五之Selenium的用法 | 靜覓

Python爬蟲實戰八之利用Selenium抓取淘寶匿名旺旺 | 靜覓

通過Python抓取天貓評論數據

Python Package Index


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM