1. 程式人生 > >python-爬蟲技能升級記錄

python-爬蟲技能升級記錄

====== python-爬蟲技能升級記錄 ======

===== (一)感知爬蟲及爬取流程 =====
<code>
從簡單存取一個頁面到 爬取到大量的定量資料,對技術要求更高,以百度百科資料爬取為入門練手專案.歷時一個月,經歷很多問題.

爬取流程:分析目標網頁、得到url、拿url抓取、解析抓到的頁面、存取資料和解析出的url、去重 繼續迭代抓。

通過擴大關鍵詞範圍、從頁面提取更多相關url源來覆蓋更多可抓頁,提升抓取資料量。
chrome瀏覽器F12是個好工具,把網頁解析過程看的一目瞭然。
練好正則表示式,用好用熟python的各個爬蟲工具庫。
爬蟲這個活,很鍛鍊分析he提取資訊能力。

提高抓取速度,速度,速度.

</code>
===== (二)那些問題 =====

<code>
2.1 溝通上的問題:爬和存最終是要百度百科某個詞條的完整頁面,我誤以為是要進一步析取頁面某個部分的結果,浪費了點時間去練沒用到的正則表示式;
2.2 爬取過程中發現問題的能力:
    爬取的前2天,資料從大量快速增長 到突然降到很小,爬取很突然變慢,結果是缺資料庫索引 資料查詢操作變慢拖累了爬取速度,
    --------> 需要隨時觀察資料量變化及時把握住趨勢 提早解決問題;

    每天評估抓取速度he目標資料量差距,提前開源--找新的關鍵詞或者新的抓取方式抓取源頭;

2.3 爬蟲背景知識欠缺:http_status, 200 301,302,代理,併發

2.4 資料上的問題
   1) 遇到多義詞的特殊頁面 : https://baike.baidu.com/item/%E6%88%BF%E4%BA%A7 ;
   2) 拼接關鍵詞錯誤 : https://baike.baidu.com/item/https://baike.baidu.com/error.html ;
   3) 不存在的頁面處理問題: https://baike.baidu.com/error.html
   
</code>

==== [0001] url解析問題 ====結果

<code>
抓資料過程中,要從抓來的網頁內容 提取url和所需關鍵字 ,用 urllib.parse.urlparse提取 路徑,urllib.parse.unquote解碼
比如 提取到url https://baike.baidu.com/item/%E5%86%8D%E7%94%9F%E4%B9%8B%E7%8E%8B%E6%9C%9D --> /item/再生之王朝

</code>

==== [0002] mysql crash了 ====
<code>
[問題]:資料 20G時,db crash,200w的資料 int型別的欄位上 index 重建 花了 1.5小時,追查無果
[解決]:是記憶體耗盡,導致mysql的資料庫索引檔案損壞。
mysql修復命令:
myisamchk  --force --update-state --sort_buffer_size=2G  /data/mysql/data/baidu/baidu_baike
</code>
==== [0003] 302是啥?allow_redirects的作用 ====

<code>
302是一種重定向狀態碼,表明,要取得最終結果需要進一步請求.

301   (永久移動)  請求的網頁已永久移動到新位置。 伺服器返回此響應(對 GET 或 HEAD 請求的響應)時,會自動將請求者轉到新位置。
302   (臨時移動)  伺服器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。
303   (檢視其他位置) 請求者應當對不同的位置使用單獨的 GET 請求來檢索響應時,伺服器返回此程式碼。
304   (未修改) 自從上次請求後,請求的網頁未修改過。 伺服器返回此響應時,不會返回網頁內容。
305   (使用代理) 請求者只能使用代理訪問請求的網頁。 如果伺服器返回此響應,還表示請求者應使用代理。
307   (臨時重定向)  伺服器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。

url = 'https://pan.baidu.com/s/1c0rjnbi'
tml = requests.get(url, headers=headers, allow_redirects=False)
return html.headers['Location']
allow_redirects=False的意義為拒絕預設的301/302重定向從而可以通過html.headers[‘Location’]拿到重定向的URL

https://baike.baidu.com/view/38072.html
urllib.error.HTTPError: HTTP Error 302: The HTTP server returned a redirect error that would lead to an infinite loop

</code>

==== [0004] 多thread的段錯誤問題 ====

起多個抓取thread ,執行一段時間報段錯誤 抓取程式崩潰--> mysql-connector.x86_64的包問題,換 mysql-connector_2.1.4 或者 pymysql後解決。

<code>[115686.825855] python3.5[112899]: segfault at 50 ip 00007f506bc70ba1 sp 00007f506a823f40 error 4 in _mysql_connector.cpython-35m-x86_64-linux-gnu.so[7f506bc1a000+3b9000]
[116821.355924] python3.5[122287]: segfault at 50 ip 00007fb8aedfeba1 sp 00007fb8ad9b1f40 error 4 in _mysql_connector.cpython-35m-x86_64-linux-gnu.so[7fb8aeda8000+3b9000]
[117432.277293] python3.5[124563]: segfault at 50 ip 00007f3e80cebba1 sp 00007f3e7f89ef40 error 4 in _mysql_connector.cpython-35m-x86_64-linux-gnu.so[7f3e80c95000+3b9000]
[117682.160350] python3.5[129646]: segfault at 50 ip 00007feea0327ba1 sp 00007fee9ef1af40 error 4 in _mysql_connector.cpython-35m-x86_64-linux-gnu.so[7feea02d1000+3b9000]
[117891.158342] python3.5[633]: segfault at 50 ip 00007ff5d0581ba1 sp 00007ff5cf174f40 error 4 in _mysql_connector.cpython-35m-x86_64-linux-gnu.so[7ff5d052b000+3b9000]
</code>


==== [0005] XHR是啥? ====
XMLHttpRequest,動態非同步請求。
[[https://www.cnblogs.com/syfwhu/p/6116323.html| XHR簡介 ]]
[[https://blog.csdn.net/zhiruchen/article/details/50983371|觀察資料-分析-構造請求-結果]]
[[https://blog.csdn.net/zwq912318834/article/details/78364710|XHR-尋找引數來源]]


[[https://blog.jamespan.me/2016/02/28/mysql-select-from-update|mysql-select-from-update]]

==== [0006] 遇到cookie了 ====

<code>
url = "https://baike.baidu.com/wikiui/api/getcertifyinfo?lemma={0}".format("%E5%8C%97%E4%BA%AC%E5%85%AB%E5%8F%8B%E7%A7%91%E6%8A%80%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8")
    headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8',
            'X-Requested-With': 'XMLHttpRequest',
        }
    
    session = requests.Session()
    respn = session.post(url, verify = False, headers = headers, allow_redirects=False)

    # https://baike.qixin.com/?eid=ea2b58fa-0b3f-440c-9076-d8735fdcc882&token=6018b5609a2c2ccf4cb8e4915ffcc4a7
    sec_url = eval(respn.text)['data']['iframe'].replace('\/','/')
    print('--sec_url--:' , sec_url)

    cookie_jar = RequestsCookieJar()
    cookie = respn.cookies.get_dict()
    for k, v in cookie.items():
        cookie_jar.set(k, v, domain="baidu.com")
    print('cookie---', cookie, '\n--',str(cookie_jar))
    

    rtext2 = session.post(sec_url, verify = False, headers = headers, cookies=cookie_jar, allow_redirects=False).text

    print('rtext2--:\n' , rtext2)
</code>

[[https://blog.csdn.net/hpulfc/article/details/80084398| python--獲取和設定cookie]]

==== [0007] 再探requests庫 ====

python的變數引用原理, requests的post和get, requests的session的文件和用途;

==== [0098] 爬取速度可能慢的因素 ====

1. 多執行緒處理到同樣任務,造成浪費;

2. 涉及到db操作的, 抓取佇列長度和 db佇列處理長度的最佳匹配;


==== [0099] 爬蟲的除錯 ====
<code>
 python的開發技能上:

1. 一定要了解整個抓取處理的流程;
2. 每個流程的環節打日誌看消耗的時長;
3. 對目標資料量和程式的處理能力有清晰的感知;
4. 別瞎猜, 打日誌看.

Linux系統有關:
 1. 段錯誤出現後及時看dmesg ,能看到是mysql聯結器的包報出異常;


</code>
===== (三)欠缺之處和待提升的技能 =====
欠缺之處:

梳理問題能力要鍛鍊he提升, 進入狀態慢,在開發進度把控上欠缺節奏感。


爬蟲技術待提升技能:
併發, 非同步, cookie,登入,驗證碼


----

[[https://github.com/davisking/dlib/issues/1104|段錯誤-參考資料 (the most important rule when writing multithreaded applications is that you can't have two threads modifying the same thing at the same time)]]