摘要:本次使用天天基金網(wǎng)進行爬蟲,該網(wǎng)站具有反爬機制,同時數(shù)量足夠大,多線程效果較為明顯。技術(shù)路線代理池多線程爬蟲與反爬編寫思路首先,開始分析天天基金網(wǎng)的一些數(shù)據(jù)。一旦使用多線程,則需要考慮到數(shù)據(jù)的讀寫順序問題。
@[TOC]
簡介提到爬蟲,大部分人都會想到使用Scrapy工具,但是僅僅停留在會使用的階段。為了增加對爬蟲機制的理解,我們可以手動實現(xiàn)多線程的爬蟲過程,同時,引入IP代理池進行基本的反爬操作。
本次使用天天基金網(wǎng)進行爬蟲,該網(wǎng)站具有反爬機制,同時數(shù)量足夠大,多線程效果較為明顯。
技術(shù)路線IP代理池
多線程
爬蟲與反爬
編寫思路首先,開始分析天天基金網(wǎng)的一些數(shù)據(jù)。經(jīng)過抓包分析,可知:
./fundcode_search.js包含所有基金的數(shù)據(jù),同時,該地址具有反爬機制,多次訪問將會失敗的情況。
同時,經(jīng)過分析可知某只基金的相關(guān)信息地址為:fundgz.1234567.com.cn/js/ + 基金代碼 + .js
分析完天天基金網(wǎng)的數(shù)據(jù)后,搭建IP代理池,用于反爬作用。點擊這里搭建代理池,由于該作者提供了一個例子,所以本代碼里面直接使用的是作者提供的接口。如果你需要更快速的獲取到普匿IP,則可以自行搭建一個本地IP代理池。
# 返回一個可用代理,格式為ip:端口 # 該接口直接調(diào)用github代理池項目給的例子,故不保證該接口實時可用 # 建議自己搭建一個本地代理池,這樣獲取代理的速度更快 # 代理池搭建github地址https://github.com/1again/ProxyPool # 搭建完畢后,把下方的proxy.1again.cc改成你的your_server_ip,本地搭建的話可以寫成127.0.0.1或者localhost def get_proxy(): data_json = requests.get("http://proxy.1again.cc:35050/api/v1/proxy/?type=2").text data = json.loads(data_json) return data["data"]["proxy"]
搭建完IP代理池后,我們開始著手多線程爬取數(shù)據(jù)的工作。一旦使用多線程,則需要考慮到數(shù)據(jù)的讀寫順序問題。這里使用python中的隊列queue進行存儲基金代碼,不同線程分別從這個queue中獲取基金代碼,并訪問指定基金的數(shù)據(jù)。由于queue的讀取和寫入是阻塞的,所以可以確保該過程不會出現(xiàn)讀取重復和讀取丟失基金代碼的情況。
# 將所有基金代碼放入先進先出FIFO隊列中 # 隊列的寫入和讀取都是阻塞的,故在多線程情況下不會亂 # 在不使用框架的前提下,引入多線程,提高爬取效率 # 創(chuàng)建一個隊列 fund_code_queue = queue.Queue(len(fund_code_list)) # 寫入基金代碼數(shù)據(jù)到隊列 for i in range(len(fund_code_list)): #fund_code_list[i]也是list類型,其中該list中的第0個元素存放基金代碼 fund_code_queue.put(fund_code_list[i][0])
現(xiàn)在,開始編寫如何獲取指定基金的代碼。首先,該函數(shù)必須先判斷queue是否為空,當不為空的時候才可進行獲取基金數(shù)據(jù)。同時,當發(fā)現(xiàn)訪問失敗時,則必須將我們剛剛?cè)〕龅幕鸫a重新放回到隊列中去,這樣才不會導致基金代碼丟失。
# 獲取基金數(shù)據(jù) def get_fund_data(): # 當隊列不為空時 while (not fund_code_queue.empty()): # 從隊列讀取一個基金代碼 # 讀取是阻塞操作 fund_code = fund_code_queue.get() # 獲取一個代理,格式為ip:端口 proxy = get_proxy() # 獲取一個隨機user_agent和Referer header = {"User-Agent": random.choice(user_agent_list), "Referer": random.choice(referer_list) } try: req = requests.get("http://fundgz.1234567.com.cn/js/" + str(fund_code) + ".js", proxies={"http": proxy}, timeout=3, headers=header) except Exception: # 訪問失敗了,所以要把我們剛才取出的數(shù)據(jù)再放回去隊列中 fund_code_queue.put(fund_code) print("訪問失敗,嘗試使用其他代理訪問")
當訪問成功時,則說明能夠成功獲得基金的相關(guān)數(shù)據(jù)。當我們在將這些數(shù)據(jù)存入到一個.csv文件中,會發(fā)現(xiàn)數(shù)據(jù)出現(xiàn)錯誤。這是由于多線程導致,由于多個線程同時對該文件進行寫入,導致出錯。所以需要引入一個線程鎖,確保每次只有一個線程寫入。
# 申請獲取鎖,此過程為阻塞等待狀態(tài),直到獲取鎖完畢 mutex_lock.acquire() # 追加數(shù)據(jù)寫入csv文件,若文件不存在則自動創(chuàng)建 with open("./fund_data.csv", "a+", encoding="utf-8") as csv_file: csv_writer = csv.writer(csv_file) data_list = [x for x in data_dict.values()] csv_writer.writerow(data_list) # 釋放鎖 mutex_lock.release()
至此,大部分工作已經(jīng)完成了。為了更好地實現(xiàn)偽裝效果,我們對header進行隨機選擇。
# user_agent列表 user_agent_list = [ "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.71 Safari/537.1 LBBROWSER", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)", "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.84 Safari/535.11 SE 2.X MetaSr 1.0", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.4.3.4000 Chrome/30.0.1599.101 Safari/537.36", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 UBrowser/4.0.3214.0 Safari/537.36" ] # referer列表 referer_list = [ "http://fund.eastmoney.com/110022.html", "http://fund.eastmoney.com/110023.html", "http://fund.eastmoney.com/110024.html", "http://fund.eastmoney.com/110025.html" ] # 獲取一個隨機user_agent和Referer header = {"User-Agent": random.choice(user_agent_list), "Referer": random.choice(referer_list) }
最后,在main中,開啟線程即可。
# 創(chuàng)建一個線程鎖,防止多線程寫入文件時發(fā)生錯亂 mutex_lock = threading.Lock() # 線程數(shù)為50,在一定范圍內(nèi),線程數(shù)越多,速度越快 for i in range(50): t = threading.Thread(target=get_fund_data,name="LoopThread"+str(i)) t.start()
通過對多線程和IP代理池的實踐操作,能夠更加深入了解多線程和爬蟲的工作原理。當你在使用一些爬蟲框架的時候,就能夠做到快速定位錯誤并解決錯誤。
數(shù)據(jù)格式000056,建信消費升級混合,2019-03-26,1.7740,1.7914,0.98,2019-03-27 15:00
000031,華夏復興混合,2019-03-26,1.5650,1.5709,0.38,2019-03-27 15:00
000048,華夏雙債增強債券C,2019-03-26,1.2230,1.2236,0.05,2019-03-27 15:00
000008,嘉實中證500ETF聯(lián)接A,2019-03-26,1.4417,1.4552,0.93,2019-03-27 15:00
000024,大摩雙利增強債券A,2019-03-26,1.1670,1.1674,0.04,2019-03-27 15:00
000054,鵬華雙債增利債券,2019-03-26,1.1697,1.1693,-0.03,2019-03-27 15:00
000016,華夏純債債券C,2019-03-26,1.1790,1.1793,0.03,2019-03-27 15:00
功能截圖 配置說明# 確保安裝以下庫,如果沒有,請在python3環(huán)境下執(zhí)行pip install 模塊名 import requests import random import re import queue import threading import csv import json補充
完整版源代碼存放在github上,有需要的可以下載
項目持續(xù)更新,歡迎您star本項目
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/43487.html
摘要:今天為大家整理了個爬蟲項目。地址新浪微博爬蟲主要爬取新浪微博用戶的個人信息微博信息粉絲和關(guān)注。代碼獲取新浪微博進行登錄,可通過多賬號登錄來防止新浪的反扒。涵蓋鏈家爬蟲一文的全部代碼,包括鏈家模擬登錄代碼。支持微博知乎豆瓣。 showImg(https://segmentfault.com/img/remote/1460000018452185?w=1000&h=667); 今天為大家整...
摘要:時間永遠都過得那么快,一晃從年注冊,到現(xiàn)在已經(jīng)過去了年那些被我藏在收藏夾吃灰的文章,已經(jīng)太多了,是時候把他們整理一下了。那是因為收藏夾太亂,橡皮擦給設置私密了,不收拾不好看呀。 ...
摘要:面向?qū)ο蟮姆植际脚老x框架一簡介概述是一個面向?qū)ο蟮姆植际脚老x框架。分布式集群集群方式維護爬蟲爬蟲運行數(shù)據(jù),可通過或定制實現(xiàn)。 《面向?qū)ο蟮姆植际脚老x框架XXL-CRAWLER》 showImg(https://segmentfault.com/img/remote/1460000011842697);showImg(https://segmentfault.com/img/remote...
摘要:優(yōu)雅的使用框架,爬取唐詩別苑網(wǎng)的詩人詩歌數(shù)據(jù)同時在幾種動態(tài)加載技術(shù)中對比作選擇雖然差不多兩年沒有維護,但其本身是一個優(yōu)秀的爬蟲框架的實現(xiàn),源碼中有很多值得參考的地方,特別是對爬蟲多線程的控制。 優(yōu)雅的使用WebMagic框架,爬取唐詩別苑網(wǎng)的詩人詩歌數(shù)據(jù) 同時在幾種動態(tài)加載技術(shù)(HtmlUnit、PhantomJS、Selenium、JavaScriptEngine)中對比作選擇 We...
摘要:學習網(wǎng)絡爬蟲主要分個大的版塊抓取,分析,存儲另外,比較常用的爬蟲框架,這里最后也詳細介紹一下。網(wǎng)絡爬蟲要做的,簡單來說,就是實現(xiàn)瀏覽器的功能。 Python學習網(wǎng)絡爬蟲主要分3個大的版塊:抓取,分析,存儲 另外,比較常用的爬蟲框架Scrapy,這里最后也詳細介紹一下。 首先列舉一下本人總結(jié)的相關(guān)文章,這些覆蓋了入門網(wǎng)絡爬蟲需要的基本概念和技巧:寧哥的小站-網(wǎng)絡爬蟲,當我們在瀏覽器中輸入...
閱讀 823·2021-11-18 10:02
閱讀 2542·2021-11-11 16:54
閱讀 2765·2021-09-02 09:45
閱讀 664·2019-08-30 12:52
閱讀 2791·2019-08-29 14:04
閱讀 2757·2019-08-29 12:39
閱讀 460·2019-08-29 12:27
閱讀 1897·2019-08-26 13:23