1. 程式人生 > >【爬蟲筆記1】改進——基於selenium和影象識別的百度指數爬蟲

【爬蟲筆記1】改進——基於selenium和影象識別的百度指數爬蟲

最近在和小夥伴一同做一個有關投資者情緒分析的專案,除了實現一些文字挖掘的演算法外,其實這個專案絕大部分的任務量是在文字資料的獲取上,也就是網路爬蟲。以前雖學了些H5+CSS網路開發的技術,但網路爬蟲接觸很少,索性花了點時間把爬蟲技術從頭到尾學了一遍。這不到一個月來,利用閒餘時間完成了百度指數、東方財富網和新浪微博的批量爬蟲。這三個網站的爬蟲較之傳統網站都不是省油的燈,例如,百度指數網上的指數資料無法直接提取、東方財富網是經過Javascript渲染過後的網頁並且還需經過先從文章列表中提取文章連結再爬取連結中的文章的兩步爬取過程、新浪微博反爬蟲太強並且微博提取過程中牽涉到一些模擬網頁動作鏈的實現;做的過程中著實碰壁不少,後續擬撰寫幾篇部落格一一解讀,並總結我這段時間的爬蟲經驗與心得。會了自然通,我個人覺得爬蟲主要還是流程程式碼的實現,還是比較簡單的,不過學習爬蟲有助於理解網頁結構、理解網頁開發的原理,我個人也推薦學一些簡單的爬蟲實現,一定會有收穫。

(1)模擬登陸。這個還算好,因為一次登入後瀏覽器直接生成會話,後續無需重複登入,所以也不用完全實現自動化模擬登陸,就像baseline程式碼中實現的一樣,先使用selenium模擬登陸,再加上一個input等待人工確認是否登入完畢,若需要輸手機驗證碼就手動輸一下後確認登入。

(2)百度指數獲取。百度指數的資料並不是以數值形式儲存在網頁上的,只有當鼠標出現在曲線上才會跳出百度指數,因此需要模擬滑鼠移動截圖跳出來的百度指數,再通過影象識別方法獲取百度指數。

Baseline程式碼已基本實現了這兩個難點的操作,我又繼續優化了三個地方:

(1)Baseline程式碼過多地使用time.sleep()函式等待頁面載入,可以使用selenium.webdriver.support.ui.WebDriverWait顯示等待頁面的某個元素是否存在來判斷頁面是否載入完畢。

  • Baseline程式碼模擬登入:
# 原始碼模擬登陸操作
    # 輸入賬號密碼
    # 輸入賬號密碼
    account = []
    try:
        fileaccount = open("../baidu/account.txt", encoding='UTF-8')
        accounts = fileaccount.readlines()
        for acc in accounts:
            account.append(acc.strip())
        fileaccount.close()
    except Exception as err:
        print(err)
        input("請正確在account.txt裡面寫入賬號密碼")
        exit()
    print(account[0])
    print(account[1])
    time.sleep(2)
    browser.find_element_by_id("TANGRAM__PSP_3__footerULoginBtn").click()
    time.sleep(2)
    browser.find_element_by_id("TANGRAM__PSP_3__userName").send_keys(account[0])
    time.sleep(2)
    browser.find_element_by_id("TANGRAM__PSP_3__password").send_keys(account[1])

    # 點選登陸登陸
    # id="TANGRAM__PSP_3__submit"
    browser.find_element_by_id("TANGRAM__PSP_3__submit").click()
  • 改進的模擬登陸:
# 改進的顯示等待
    # 輸入賬號密碼
    # 輸入賬號密碼
    account = []
    try:
        fileaccount = open("./account.txt", encoding='UTF-8')
        accounts = fileaccount.readlines()
        for acc in accounts:
            account.append(acc.strip())
        fileaccount.close()
    except Exception as err:
        print(err)
        input("請正確在account.txt裡面寫入賬號密碼")
        exit()
    print(account[0])
    print(account[1])
    footer_login_btn = wait.until(EC.presence_of_element_located((By.ID,       "TANGRAM__PSP_3__footerULoginBtn")))
    footer_login_btn.click()

    username_input = wait.until(EC.presence_of_element_located((By.ID, "TANGRAM__PSP_3__userName")))
    password_input = wait.until(EC.presence_of_element_located((By.ID, "TANGRAM__PSP_3__password")))
    login_btn = wait.until(EC.presence_of_element_located((By.ID, "TANGRAM__PSP_3__submit")))
    username_input.send_keys(account[0])
    password_input.send_keys(account[1])
    login_btn.click()

(2)使用百度雲人工智慧影象文字識別API,基礎文字識別每天有50000次免費呼叫,精度比pytesseract.image_to_string()的ocr識別高多了,此外baseline程式碼只提取了百度指數的數值,沒有提取時間,我也加進去了,修改了圖片擷取大小,在百度雲API識別圖片後用正則化提取出了時間。

  • Baseline程式碼的影象擷取與識別過程
imgelement = browser.find_element_by_xpath('//div[@id="viewbox"]')
# 找到圖片座標
locations = imgelement.location
# 跨瀏覽器相容
scroll = browser.execute_script("return window.scrollY;")
top = locations['y'] - scroll
# 找到圖片大小
sizes = imgelement.size
# 構造關鍵詞長度
add_length = (len(keyword) - 2) * sizes['width'] / 15
# 構造指數的位置
rangle = (
    int(locations['x'] + sizes['width'] / 4 + add_length), int(top + sizes['height'] / 2),
    int(locations['x'] + sizes['width'] * 2 / 3), int(top + sizes['height']))
time.sleep(2)
# 擷取當前瀏覽器
path = "../baidu/" + str(num)
browser.save_screenshot(str(path) + ".png")
# 開啟截圖切割
img = Image.open(str(path) + ".png")
jpg = img.crop(rangle)
jpg.save(str(path) + ".jpg")

# 將圖片放大一倍
# 原圖大小73.29
jpgzoom = Image.open(str(path) + ".jpg")
(x, y) = jpgzoom.size
x_s = 146
y_s = 58
out = jpgzoom.resize((x_s, y_s), Image.ANTIALIAS)
out.save(path + 'zoom.jpg', 'png', quality=95)

# 影象識別
try:
    image = Image.open(str(path) + "zoom.jpg")
    code = pytesseract.image_to_string(image) # pytesseract的ocr識別,精度一般
    if code:
        index.append(code)
    else:
        index.append("")
except:
    index.append("")
num = num + 1
  • 改進的影象擷取與識別過程
# 原始碼影象擷取與識別過程
imgelement = browser.find_element_by_xpath('//div[@id="viewbox"]')

# 找到viewbox座標
locations = imgelement.location

# 跨瀏覽器相容
scroll = browser.execute_script("return window.scrollY;")
top = locations['y'] - scroll

# 找到viewbox大小
sizes = imgelement.size
# 構造文字與資料位置
rangle = (
    int(locations['x']), int(top),
    int(locations['x'] + sizes['width']), int(top + sizes['height']))

# 擷取當前瀏覽器
if day <= 180:
    file = './' + keyword + '_' + str(day) + '/image/'
else:
    file = './' + keyword + '_' + 'all'  + '/image/'

if not os.path.exists(file):
    os.makedirs(file)
path = file + str(num)
browser.save_screenshot(str(path) + "_raw.png")

# 開啟截圖切割
img = Image.open(str(path) + "_raw.png")
jpg = img.crop(rangle)
jpg.save(str(path) + "_cropped.png")

# 影象識別
try:
    image = get_file_content(str(path) + "_cropped.png")
    code = client.basicGeneral(image)   # 百度雲文字識別api 
    print('code : ', code)
    if day <= 180:
        r1 = re.compile('(\d+).*')
        r2 = re.compile('\D+(\d+)')
    else:
        r1 = re.compile('(\d+\D\d+).*')
        r2 = re.compile('\D+(\d+)')

    dict = {}
    dict['time'] = r1.findall(code['words_result'][0].get('words').strip().replace('-', ''))[0]
    dict['index'] = int(r2.findall(code['words_result'][1].get('words').strip().replace(',', '').replace('■', ''))[0])
    print('dict: ', dict)
    index.append(dict)
except:
    index.append("")

num = num + 1

(3)Baseline程式碼中設定的滑鼠移動的動作鏈的步長並不具有普適性,可能這套步長設定只適合他的瀏覽器卻不適合其他的,可能因為步長過大而漏掉了一些指數。那麼我寧願將步長設定的很小,儘管會有重複,但是可以保證每一個指數都被提取到,後續再判斷去重即可。雖然採取小步長會很慢,但是百度指數一次提取後便可複用以後只需更新最新的,所以慢就慢點吧,可以晚上睡覺時候一次性設定好關鍵詞條跑完。

  • Baseline程式碼動作鏈步長設定
# 原始碼動作鏈步長設定
for i in range(day):
    # 座標偏移量
    ActionChains(browser).move_to_element_with_offset(xoyelement, x_0, y_0).perform()

    # 構造規則
    if day == 7:
        x_0 = x_0 + 202.33
    elif day == 30:
        x_0 = x_0 + 41.68
    elif day == 90:
        x_0 = x_0 + 13.64
    elif day == 180:
        x_0 = x_0 + 6.78
    elif day == 1000000:
        x_0 = x_0 + 3.37222222
    time.sleep(2)
  • 改進的動作鏈步長設定
# 改進的動作鏈步長設定
ActionChains(browser).move_to_element_with_offset(xoyelement, 1100, 50).perform()
time.sleep(1)
while True:
    # 座標偏移量
    ActionChains(browser).move_to_element_with_offset(xoyelement, x_0, y_0).perform()
    time.sleep(1)
    # 構造規則
    if day == 1:
        x_0 = x_0 + 20
        if x_0 > 1200:
            break
    elif day == 7:
        x_0 = x_0 + 40
        if x_0 > 1200:
            break
     elif day == 30:
        x_0 = x_0 + 20
        if x_0 > 1200:
            break
     elif day == 90:
        x_0 = x_0 + 5
        if x_0 > 1200:
            break
     elif day == 180:
        x_0 = x_0 + 3
        if x_0 > 1200:
            break
     else:
        x_0 = x_0 + 1
        if x_0 > 1200:
            break

綜上,便是基於baseline程式碼的改進,再次感謝baseline程式碼給我的基礎。改進的完整程式碼請戳我的github:https://github.com/shaoniangu/Baidu_index_spider。後續幾篇部落格將陸續完成。

-------------------------------------------

Youzhi Gu, master student

Foresight Control Center

College of Control Science & Engineering

Zhejiang University

Email: [email protected]

相關推薦

爬蟲筆記1改進——基於selenium影象識別指數爬蟲

最近在和小夥伴一同做一個有關投資者情緒分析的專案,除了實現一些文字挖掘的演算法外,其實這個專案絕大部分的任務量是在文字資料的獲取上,也就是網路爬蟲。以前雖學了些H5+CSS網路開發的技術,但網路爬蟲接觸很少,索性花了點時間把爬蟲技術從頭到尾學了一遍。這不到一個月來,利用閒餘時

MYSQL筆記1mysql的基礎知識

首先進去mysql。開啟電腦命令提示符(cmd);輸入mysql -uroot -p   代表的意思是使用ruser使用者root的方式,開啟mysql,-p代表password,如果有的話,回車之後再輸入密碼在回車就進去mysql環境了 在>提示符符號後面就可以輸入mysql

演算法筆記 - 1多項式乘法 —— FFT

目錄 @0 - 參考資料@ @1 - 一些概念@ @2 - 傅立葉正變換@ @3 - 傅立葉逆變換@ @4 - 迭代實現 [email protected] @5 - 參考程式碼實現@ @6 - 快速數論變換 [email protected] @

論文筆記1RNN在影象壓縮領域的運用——Variable Rate Image Compression with Recurrent Neural Networks

一、引言 隨著網際網路的發展,網路圖片的數量越來越多,而使用者對網頁載入的速度要求越來越高。為了滿足使用者對網頁載入快速性、舒適性的服務需求,如何將影象以更低的位元組數儲存(儲存空間的節省意味著更快的傳輸速度)並給使用者一個低解析度的thumbnails(縮圖)的previ

學習筆記1吳恩達_卷積神經網路_第一週卷積神經網路(1

一、卷積神經網路 1.邊緣檢測 不同的語言中表示卷積的函式不同,在Python中為在tensorflow裡為 濾波器:垂直、水平邊緣檢測。 Sobel filter:其優點在於增加了中間一行元素的權重,即影象中間的畫素點提高,會使結果的魯棒(robust)性提高。

深度學習筆記1如何建立確定模型正確性?如何優化模型?

近期看了吳恩達的一本書,關於如何建立和確定優化模型?裡面有個人認為需要學習的地方,故做筆記: 1.模型訓練一共有三個資料集:訓練集、開發集(驗證集)、測試集。開發集不能太小,通常在1000-10000,並且測試集屬於同一分佈;2.過擬合:訓練過程中開發集的準確率和測試集測試的準確率差別不大,若開發集比測試集

清華AI自強計劃-計算機視覺課程-第三講課程筆記1

【清華AI自強計劃】-第三講課程筆記-1 資料歸一化中的“一”是什麼意思? 將不同變數的量綱都轉化為1,消除單位的影響。 明確課程定位: 垂直行業從業者&愛好者: 聽課目標:0->0.5 定性理解,專注落地 演算法科學家: 聽課目標:0->1

爬蟲例項1python3下使用beautifulsoup爬取資料並存儲txt檔案

1:執行環境: python: 3.7.0 系統:Windows IDE:pycharm 2017 2:需要安裝的庫: requests 和 beautifulsoup 3:完整程式碼: # cod

學習心得 筆記 1大疆技術總監:如何用六年成為一個全能的機器人工程師

origin: http://www.elecfans.com/app/api/focus/index/id/438628?from=singlemessage&isappinstalled=1     機器人學的核心問題是做好和物理世界的互動。現在主流的機器人學分支裡,處

爬蟲入門1css選擇器

css選擇器 css選擇器:一種快速定位元素的方法 基本用法<1> * 選擇所有元素 .class .intro 選擇所有class="intro"的元素 #id #firstname 選擇所有id = "firstname"的元素 elemen

SpringMVC學習指南筆記1建立bean例項的方法依賴注入

Spring MVC 主要從Spring框架、Servlet、JSP這3個方面來講。   Java企業版技術包括JMS、EJB、JSF、JPA。   Java企業版容器:GlassFish、JBoss、Oracle、Weblogic、IBM WebSphere   T

SpringMVC學習指南筆記1創建bean實例的方法依賴註入

tro ans tex 多個 oracle sys 實例 不同的 指定 Spring MVC 主要從Spring框架、Servlet、JSP這3個方面來講。 Java企業版技術包括JMS、EJB、JSF、JPA。 Java企業版容器:GlassFish、JBoss、

Swift 3.1iOS開發筆記(四)

  一、唱片旋轉效果(360°無限順時針旋轉) func animationRotateCover() { coverImageView.layer.removeAllAnimations() let animation = CABasicAnim

微信小程式筆記-1基本構成及配置

此筆記作為學習過程中筆記,作為存檔並藉此分享,如有錯誤感謝指出 此筆記大量參考微信官方開發者文件以及“軟謀教育課程(這個課程在騰訊課堂是免費的,算是我現在看到的比較好的視訊教程)”,如有版權問題請及時與我聯絡刪除 一、程式碼構成 微信小程式基本檔案

Robot定位 學習筆記 1GPSIMU(慣導)在無人駕駛中的應用

無人駕駛定位技術 行車定位是無人駕駛最核心的技術之一,全球定位系統(GPS)在無人駕駛定位中也擔負起相當重要的職責。然而無人車是在複雜的動態環境中行駛,尤其在大城市,GPS多路徑反射的問題會很明顯。這樣得到的GPS定位資訊很容易就有幾米的誤差。對於在有限寬度高速行駛的汽車來說,這樣的誤差很有可能

Algorithms公開課學習筆記1 Union-Find 合併查詢

Union-Find 合併查詢 動態連線性 判斷連線性的關鍵 等價關係模型:如果有(a,b),(b,c),那麼也會有(a,c)。其中()表示有連線。 連通分量:最大的可連通物件集合,有兩個特點:1)連通分量內部任意兩個物件都是相連通的;2)連通分量內

機器學習筆記1Logistic迴歸總結

 Logistic迴歸總結 作者:洞庭之子 (2013年11月) 1.引言 看了Stanford的Andrew Ng老師的機器學習公開課中關於Logistic Regression的講解,然後又看了《機器學習實戰》中的LogisticRegression部分,

Servlet學習筆記-1使用Eclipse建立第一個Servlet並在html頁面呼叫示例

說明:學習過程中參考了很多資料,但此文章主要在https://www.studytonight.com/servlet/creating-servlet-in-eclipse的基礎上調整完成,如果侵權請

《重構 改善既有代碼的設計》學習筆記1重構:第一個案例

作者 mta 而不是 cto 對象 ppm ice tegra 思考 【《重構 改善既有代碼的設計》學習筆記】重構:第一個案例 本篇文章的內容來自《重構 改善既有代碼的設計》一書學習筆記整理筆記並且加上自己的淺顯的思考總結! 一、簡單的例子 一個影片出租店用的程序,計算

分類——筆記01基於稀疏編碼的半監督影象分類研究

/****************************************************************************** 1.《基於稀疏編碼的半監督影象分類研究》 作者:陳漢英 學科:計算機應用技術 完成時間:2014年4月 *****