python爬蟲--【百度知道】自動答題

  • 做的第一個python爬蟲類項目,剛開始學,如有錯誤,指出無妨

百度知道自動答題

功能

  • 訪問百度知道,我們會看到有很多新的提問。
  • 其實很多提問已經有人做了解釋或者網上可以找到現成的答案。
  • 因此,一方面,滿足那些提問題的人的需要,另一方面,自己使用python練練手。
  • 項目的主要功能就是:對於百度知道里面的新問題,程序會在網頁上去搜索,尋找最佳答案。如果有,則回答他;如果沒有,那就跳過。

實現思路

  1. 百度知道上獲取問題列表,得到的全部問題的地址鏈接,然後遍歷訪問這些鏈接,依次進入問題的詳情頁。
  2. 在問題詳情頁獲取問題題目,題目是用於搜索相關的答案
  3. 搜索答案的地址鏈接都是固定的,只要替換地址中word後面的內容即可搜索相關的答案。
  4. 得到搜索結果後,獲取答案列表的地址並遍歷訪問即可進入答案詳情頁,如果答案詳情頁裏面有最佳答案就會獲取答案內容,並且終止答案列表的遍歷。
  5. 將得到的答案寫回到問題詳情頁的回答文本框並單擊提交回答按鈕即可完成答題。
    注意:整個項目在實現過程中是用戶已登錄的情況下去執行的,百度最近的登錄驗證是滑動使圖片變正,目前我還沒有搞完它,因此獲取cookie,登錄的內容是手動的。

具體實現步驟

  • 獲取cookie,使用cookie登錄的內容
from selenium import webdriver
import json,time

driver = webdriver.Chrome()
driver.get('https://baidu.com/')
driver.find_element_by_xpath('//*[@id="u1"]/a[7]').click()
time.sleep(2)
driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__footerULoginBtn"]').click()
time.sleep(2)
driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__userName"]').send_keys('XXX')
driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__password"]').send_keys('XXXXX')
driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__submit"]').click()
time.sleep(30)


cookies = driver.get_cookies()
f1 = open('cookie.txt','w')
f1.write(json.dumps(cookies))
f1.close()
  • 如上,XXXX分別是你自己的百度賬號和密碼。當運行這段程序時,會彈出一個頁面。登錄時百度會驗證,或者是短信驗證碼或者是滑動滑塊等等,這一步是手動操作,操作完之後,程序會自動保存你的賬號和密碼在瀏覽器上的cookie值。用於下次登錄。
  • 得到用戶的登錄信息,接下來實現自動答題。整個答題過程一共涉及4個網頁:百度知道問題列表頁、百度知道問題詳情頁、答案搜索頁和答案詳情頁。
  • 在問題列表頁中,每條問題的HTML代碼是由標籤 < a> 生成,並且屬性 class 的屬性值爲 title-link,如下圖,因此 selenium 可以對屬性 class 進行定位,獲取全部問題所在的標籤 < a>,遍歷這些標籤提取相應的鏈接地址。問題列表頁- 在新的窗口訪問每條問題鏈接,這些鏈接會進入相應的問題詳情頁。在問題詳情頁中,首先判斷問題是否已被搶答,如果尚未回答,程序根據題目去百度知道搜索相關的答案,在這些相關的答案中找到最佳答案,然後寫入問題答案輸入框裏並單擊“提交回答”按鈕;如果問題已被回答,程序就關閉當前窗口,回到問題列表執行下一個問題。問題詳情頁的答案輸入框和“提交回答”按鈕的HTML代碼如下圖所示。在這裏插入圖片描述- 回答問題的過程中涉及到兩個新的網頁:答案搜索頁和答案詳情頁。答案搜索頁是根據問題在新的窗口中搜索相關答案,每個答案的鏈接以標籤< dt> 表示,該標籤下含有標籤 < a>。將selenium 定位到每個答案的的標籤< a>,在獲取 href 屬性值,該屬性值用於進入答案詳情頁。
  • 將答案詳情頁的鏈接在新的窗口裏訪問,每個答案詳情頁都不一定有最佳答案,根據分析可知,最佳答案的class 屬性值爲 best-text mb-10,如果 selenium 能對屬性 class 進行定位,則說明當前答案詳情頁有最佳答案,反之則無。
  • 根據上述的元素定位以及答題的業務邏輯,整個答題程序需要注意每個頁面窗口之間的切換,如果窗口的切換邏輯不嚴謹,很容易導致程序出錯。此外還需要考慮一些異常的情況出現,比如問題搜不到答案、問題已被回答以及網絡延時響應等一些特殊情況。綜合分析,自動答題的代碼如下:
from selenium import webdriver
import json,time

url = 'https://zhidao.baidu.com/list?cid=110'
driver = webdriver.Chrome()
driver.get(url)
# 使用cookie 登錄
driver.delete_all_cookies()
f1 = open('cookie.txt')
cookie = json.loads(f1.read())
f1.close()
for c in cookie:
    driver.add_cookie(c)
driver.refresh()

title_link = driver.find_elements_by_class_name('title-link')
print(title_link)
time.sleep(5)
for i in title_link:
    # 打開問題詳情頁並切換窗口
    driver.switch_to.window(driver.window_handles[0])
    href = i.get_attribute('href')
    driver.execute_script('window.open("%s");' % (href))
    time.sleep(5)
    driver.switch_to.window(driver.window_handles[1])
    try:
        # 查找iframe,判斷問題是否已被回答
        driver.find_element_by_id('ueditor_0')
        # 獲取問題題目並搜索答案
        title = driver.find_element_by_class_name('ask-title ').text
        title_url = 'https://zhidao.baidu.com/search?&word=' + title
        js = 'window.open("%s");' % (title_url)
        driver.execute_script(js)
        time.sleep(5)
        driver.switch_to.window(driver.window_handles[2])
        # 獲取答案列表
        answer_list = driver.find_elements_by_class_name('dt,mb-4,line')
        for k in answer_list:
            # 打開答案詳情頁
            href = k.find_element_by_tag_name('a').get_attribute('href')
            driver.execute_script('window.open("%s");' % (href))
            time.sleep(5)
            driver.switch_to.window(driver.window_handles[3])
            # 獲取最佳答案
            try:
                text = driver.find_element_by_class_name('best-text,mb-10').text
            except:
                text = ''
            finally:
                # 關閉答案詳情頁的窗口
                driver.close()
            # 答案不爲空
            if text:
                # 關閉答案列表頁的窗口
                driver.switch_to.window(driver.window_handles[2])
                driver.close()
                # 將答案寫在問題回答文本框上並提交答案按鈕
                driver.switch_to.window(driver.window_handles[1])
                driver.switch_to.frame('ueditor_0')
                driver.find_element_by_xpath('/html/body').click()
                driver.find_element_by_xpath('/html/body').send_keys(text)
                # 跳回到網頁的HTML
                driver.switch_to.default_content()
                # 單機提交回答按鈕
                driver.find_element_by_xpath('//*[@id="answer-editor"]/div[2]/a').click()
                time.sleep(5)
                # 關閉問題詳情頁的窗口
                driver.switch_to.window(driver.window_handles[1])
                driver.close()
                break
    except  Exception as err:
        # 除了問題列表頁,關閉其他窗口
        all_handles = driver.window_handles
        for i, v in enumerate(all_handles):
            if i != 0:
                driver.switch_to.window(v)
                driver.close()
        driver.switch_to.window(driver.window_handles[0])
        print(err)

  • 項目的githup地址:https://github.com/zhangyi-13572252156/Baidu-Knows-Automatic-answer/tree/master
  • 如果需要交流,歡迎交流。QQ:1251108673
發佈了170 篇原創文章 · 獲贊 98 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章