爬取国内创业公司、投资机构、独角兽公司信息
歡迎關注天善智能,我們是專注于商業智能BI,人工智能AI,大數據分析與挖掘領域的垂直社區,學習,問答、求職一站式搞定!
對商業智能BI、大數據分析挖掘、機器學習,python,R等數據領域感興趣的同學加微信:tstoutiao,邀請你進入數據愛好者交流群,數據愛好者們都在這兒。
作者:? 蘇克1900
公眾號:第2大腦
摘要:?之前爬的網站都是不需要登錄就可以爬取的,但還有很多網站的內容需要先登錄才能爬,比如桔子網、豆瓣、知乎等。這時采用之前的方法就不行了,需要先登錄再去爬。本文以桔子網為例,介紹模擬登錄方法,然后爬取該網站數據庫中的數據信息,并保存到 MongoDB 數據庫中。
1. 網站介紹
網址:https://www.itjuzi.com/
對于創投圈的人來說,國內的桔子和國外的?Crunchbase應該算是必備網站。今天,我們要說的就是前者,這個網站提供了很多有價值的信息。
信息的價值體現在哪里呢,舉個簡單的例子。你運營了一個不錯的公眾號,有著 10 萬粉絲群,這時候你想找投資繼續做大,但你不知道該到哪里去找投資。這時候你偶然發現了這個網站,在網站上你看到了同領域的大 V 號信息,他們得到了好幾家公司上千萬的投資。你看著心生羨慕,也躍躍欲試。于是,你經過綜合對比分析,對自己公眾號估值 200 萬,然后就去找投資大 V 號的那幾家公司洽談。由于目的性明確,準備也充分,你很快就得到了融資。
這個例子中,桔子網提供了創業公司(運營公眾號也是創業)融資金額和投資機構等相關寶貴的信息。當然,這只是非常小的一點價值,該網站數據庫提供了自 2000 年以來的海量數據,包括:超過11 萬家的創業公司、6 萬多條投融資信息、7 千多家投資機構以及其他數據,可以說是非常全了。這些數據的背后蘊含著大量有價值的信息。
接下來,本文嘗試爬取該網站數據庫的信息,之后做一些數據分析,嘗試找到一些有意思的信息。
主要內容:
模擬登錄
分析 Ajax 然后抓取
存儲到 MongoDB 數據庫
導出 csv
數據分析(后期)
2. 模擬登錄
2.1. Session 和 Cookies
觀察這個網站,是需要先登錄才能看到數據信息的,但是好在不用輸驗證碼。我們需要利用賬號和密碼,然后實現模擬登錄。
模擬登錄的方法有好幾種,比如 Post 直接提交賬號、先登錄獲取 Cookies 再直接請求、Selenium 模擬登錄等。其中:
Post 方法需要在后臺獲取登錄的 url,填寫表單參數然后再請求,比較麻煩;
直接復制 Cookies 的方法就是先登錄賬號,復制出 Cookies 并添加到 Headers 中,再用requests.get?方法提交請求,這種方法最為方便;
Selenium 模擬登錄方法是直接輸入賬號、密碼,也比較方便,但速度會有點慢。
之后,會單獨介紹幾種方法的具體實現的步驟。這里,我們就先采用第二種方法。
首先,需要先了解兩個知識點:Session 和 Cookies。
Session 在服務端,也就是網站的服務器,用來保存用戶的會話信息,Cookies 在客戶端,也可以理解為瀏覽器端,有了 Cookies,瀏覽器在下次訪問網頁時會自動附帶上它發送給服務器,服務器通過識別 Cookies 并鑒定出是哪個用戶,然后再判斷用戶是否是登錄狀態,然后返回對應的 Response。所以我們可以理解為 Cookies 里面保存了登錄的憑證,有了它我們只需要在下次請求攜帶 Cookies 發送 Request 而不必重新輸入用戶名、密碼等信息重新登錄了。
因此在爬蟲中,有時候處理需要登錄才能訪問的頁面時,我們一般會直接將登錄成功后獲取的 Cookies 放在 Request Headers 里面直接請求。
更多知識,可以參考崔慶才大神的文章:
https://germey.gitbooks.io/python3webspider/content/2.4-Session%E5%92%8CCookies.html
在了解 Cookies 知識后,我們就可以進入正題了。
2.2. Requests 請求登錄
首先,利用已有的賬號和密碼,登錄進網站主頁,然后右鍵-檢查,打開第一個?www.itjuzi.com請求:
向下拉到 Requests Headers 選項,可以看到有很多字段信息,這些信息之后我們都要添加到 Get 請求中去。
定位到下方的 Cookie 字段,可以看到有很多 Cookie 值和名稱,這是在登錄后自動產生的。我們將整個 Cookies 復制 Request Headers 里,然后請求網頁就可以順利登陸然后爬取。如果不加 Cookies,那么就卡在登錄界面,也就無法進行后面的爬取,所以 Cookies 很重要,需要把它放到 Request Headers 里去。
下面,我們按照 json 格式開始構造 Request Headers。這里推薦一個好用的網站,可以幫我們自動構造 Request Headers:https://curl.trillworks.com/
使用方法也很簡單,右鍵復制cURL鏈接到這個網頁中。
將 cURL 復制到左邊選框,默認選擇語言為 Python,然后右側就會自動構造后 requests 請求,包括 headers,復制下來直接可以用。登錄好以后,我們就轉到投融資速遞網頁中(url:http://radar.itjuzi.com/investevent),然后就可以獲取該頁面網頁內容了。代碼如下:
1importrequests
2headers?=?{
3'Connection':'keep-alive',
4'Cache-Control':'max-age=0',
5'Upgrade-Insecure-Requests':'1',
6'User-Agent':'Mozilla/5.0?(Windows?NT?6.1;?WOW64)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/66.0.3359.181?Safari/537.36',
7'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
8'DNT':'1',
9'Referer':'http://radar.itjuzi.com/investevent',
10'Accept-Encoding':'gzip,?deflate,?br',
11'Accept-Language':'zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7',
12'If-None-Match':'W/^\\^5bc7df15-19cdc^\\^',
13'If-Modified-Since':'Thu,?18?Oct?2018?01:17:09?GMT',
14#?主頁cookie
15'Cookie':'你的cookie',
16}
17
18url?='http://radar.itjuzi.com/investevent'#?投融資信息
19s?=?requests.Session()
20response?=?s.get(url,headers?=?headers)
21print(response.status_code)
22print(response.text)
結果如下:
可以看到,添加 Cookie 后,我們請求投融資信息網頁就成功了。這里如果不加 Cookie 的結果就什么也得不到:
好,這樣就算成功登錄了。但是整個 headers 請求頭的參數太多,是否一定需要帶這么多參數呢? 這里就去嘗試看哪些參數是請求一定要的,哪些則是不用的,不用的可以去掉以精簡代碼。經過嘗試,僅需要下面三個參數就能請求成功。
1headers?=?{
2'User-Agent':'Mozilla/5.0?(Windows?NT?6.1;?WOW64)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/66.0.3359.181?Safari/537.36'
3'X-Requested-With':'XMLHttpRequest',
4#?主頁cookie
5'Cookie':'復制你的cookie',
6}
Tips:當爬取失效的時候需要重新注冊帳號,然后生成新的 Cookie。
如果你沒那么多郵箱賬號,那么推薦一個可生成隨機賬號的免費郵箱,用來接收注冊激活鏈接:
https://10minutemail.net/
3. 網頁爬取分析
在成功登錄以后,我們就可以通過分析網頁結構來采取相應的爬取方法。這里,我們將爬取投融資速遞、創業公司、投資機構和千里馬等幾個子板塊的數據。首先,以投融資速遞信息為例。
網址:http://radar.itjuzi.com/investevent
3.1. 分析網頁
可以看到,投融資事件信息網頁中的數據是表格形式。經嘗試點擊翻頁,發現url不變,可以初步判定網頁數據采用 Ajax 形式呈現。切換到后臺,點擊翻頁可以發現出現有規律的?info?locatiop 開頭的請求,頁數隨 page 參數而發生規律的變化。
點擊請求查分別查看 Response 和 Preview,發現表格數據是 json 格式,這就太好了。因為 json 格式的數據非常整齊也很容易抓取。上一篇文章,我們正好解決了 json 格式數據的處理方法,如果不太熟悉可以回顧一下:
https://www.makcyun.top/web_scraping_withpython6.html
接著,我們就可以通過構造 url 參數,然后用 Get 請求就可以獲取網頁中的表格數據,最后再加個循環,就可以爬取多頁數據了。
3.2. 構造 url
下面,我們來構造一下 url,切換到 Headers 選項卡,拉到最底部可以看到 url 需帶的請求參數。這里有三項,很好理解。location:in,表示國內數據; orderby:def,表示默認排序;page:1,表示第一頁。所以,只需要改變 page 參數就可以查看其他頁的結果,非常簡單。
這里,如果我們對表格進行篩選,比如行業選擇教育、時間選擇 2018 年,那么相應的請求參數也會增加。通過構造參數就可以爬取指定的數據,這樣就不用全部爬下來了,也對網站友好點。
3.3. 爬取數據
到這兒,我們就可以直接開始爬了。可以使用函數,也可以用定義類(Class)的方法。考慮到,Python 是一種面向對象的編程,類(Class)是面向對象最重要的概念之一,運用類的思想編程非常重要。所以,這里我們嘗試采用類的方法來實現爬蟲。
1importrequests
2importpymongo
3importrandom
4importtime
5importjson
6importpandasaspd
7fromfake_useragentimportUserAgent
8ua?=?UserAgent()
9
10classITjuzi(object):
11def__init__(self):
12self.headers?=?{
13'User-Agent':?ua.random,
14'X-Requested-With':'XMLHttpRequest',
15'Cookie':'你的cookie',
16}
17self.url?='http://radar.itjuzi.com/investevent/info?'#?investevent
18self.session?=?requests.Session()
19
20defget_table(self,?page):
21"""
221?獲取投融資事件數據
23"""
24params?=?{#?invsestevent
25'location':'in',
26'orderby':'def',
27'page':?page,
28'date':2018#?年份
29}
30response?=?self.session.get(
31self.url,?params=params,?headers=self.headers).json()
32print(response)
33#?self.save_to_mongo(response)
34
35if__name__?=='__main__':
36spider?=?itjuzi()
37spider.get_table(1)
如果你之前一直是用 Def 函數的寫法,而沒有接觸過 Class 類的寫法,可能會看地比較別扭,我之前就是這樣的,搞不懂為什么要有 self、為什么用__init__。這種思維的轉變可以通過看教程和別人寫的實際案例去揣摩。這里,我先略過,之后會單獨介紹。
簡單解釋一下上面代碼的意思。首先定義了一個類(class),類名是?ITjuzi,類名通常是大寫開頭的單詞。后面的?(object)?表示該類是從哪個類繼承下來的,這個可以暫時不用管,填上就可以。然后定義了一個特殊的__init__方法,__init__方法的第一個參數永遠是?self,之后是其他想要設置的屬性參數。在這個方法里可以綁定些確定而且必須的屬性,比如 headers、url 等。
在 headers 里面,User-Agent 沒有使用固定的 UA,而是借助?fake_useragent包?生成隨機的 UA:ua.random。因為,這個網站做了一定的反爬措施,這樣可以起到一定的反爬效果,后續我們會再說到。接著,定義了一個 get_table() 函數,這個函數和普通函數沒有什么區別,除了第一個參數永遠是實例變量?self。在 session.get()方法中傳入 url、請求參數和 headers,請求網頁并指定獲取的數據類型為 json 格式,然后就可以順利輸出 2018 年投融資信息的第 1 頁數據:
3.4. 存儲到 MongoDB
數據爬取下來了,那么我們放到哪里呢?可以選擇存儲到 csv 中,但 json 數據中存在多層嵌套,csv 不能夠直觀展現。這里,我們可以嘗試之前沒有用過的 MongoDB 數據庫,當作練習。另外,數據存儲到該數據庫中,后期也可以導出 csv,一舉兩得。
關于 MongoDB 的安裝與基本使用,可以參考下面這兩篇教程,之后我也會單獨再寫一下:
安裝
https://germey.gitbooks.io/python3webspider/content/1.4.2-MongoDB%E7%9A%84%E5%AE%89%E8%A3%85.html
使用
https://germey.gitbooks.io/python3webspider/content/5.3.1-MongoDB%E5%AD%98%E5%82%A8.html
可視化工具可采用 Robo 3T (之前叫 RoboMongo)
https://www.mongodb.com/
下面我們就將上面返回的 json 數據,存儲到 MongoDB 中去:
1importpymongo
2importnumpyasnp
3#?mongodb數據庫初始化
4client?=?pymongo.MongoClient('localhost',27017)
5#?指定數據庫
6db?=?client.ITjuzi
7#?指定集合,類似于mysql中的表
8mongo_collection1?=?db.itjuzi_investevent
9
10defsave_to_mongo(self,?response):
11try:
12data?=?response['data']['rows']#?dict可以連續選取字典層內的內容
13df?=?pd.DataFrame(data)
14table?=?json.loads(df.T.to_json()).values()
15ifmongo_collection1.insert_many(table):#?investment
16print('存儲到mongodb成功')
17sleep?=?np.random.randint(3,7)
18time.sleep(sleep)
19exceptException:
20print('存儲到mongodb失敗')
21defspider_itjuzi(self,?start_page,?end_page):
22forpageinrange(start_page,?end_page):
23print('下載第%s頁:'%?(page))
24self.get_table(page)
25print('下載完成')
26
27if__name__?=='__main__':
28spider?=?ITjuzi()
29spider.spider_itjuzi(1,2)
這里,安裝好 MongoingDB 數據庫、Robo 3T 和 pymongo 庫后,我們就可以開始使用了。
首先,對數據庫進行初始化,然后指定(如果沒有則生成)數據將要存放的數據庫和集合名稱。接著,定義了save_to_mongo 函數。由于表格里面的數據存儲在鍵為 rows 的 value 值中,可使用?response['data']['rows']?來獲取到 json 里面的嵌套數據,然后轉為 DataFrame。DataFrame 存儲 MongoDB 參考了 stackoverflow 上面的一個答案:json.loads(df.T.to_json()).values()。
然后,使用?mongo_collection1.insert_many(table)?方法將數據插入到 mongo_collection1,也就是 itjuzi_investevent 集合中。爬取完一頁數據后,設置隨機延時 3-6 s,避免爬取太頻繁,這也能起到一定的反爬作用。
最后,我們定義一個分頁循環爬取函數?spider_itjuzi,利用 for 循環設置爬取起始頁數就可以了,爬取結果如下:
打開 Robo 3T,可以看到數據成功存儲到 MongoDB 中了:
好,以上,我們就基本上完成了 2018 年投融資信息數據表的爬取,如果你想爬其他年份或者更多頁的數據,更改相應的參數即可。
3.5. 導出到 csv
數據存好后,如果還不太熟悉 MongoDB 的對數據的操作,那么我們可以將數據導出為 csv,在 excel 中操作。MongoDB不能直接導出 csv,但操作起來也不麻煩,利用mongoexport命令,幾行代碼就可以輸出 csv。
mongoexport導出 csv 的方法:
https://docs.mongodb.com/manual/reference/program/mongoexport/#mongoexport-fields-example
首先,運行 cmd,切換路徑到 MongoDB 安裝文件夾中的 bin 目錄下,我這里是:
1cd?C:\Program?Files\MongoDB\Server\4.0\bin
接著,在桌面新建一個txt文件,命名為fields,在里面輸入我們需要輸出的表格列名,如下所示:
然后,利用mongoexport命令,按照:表格所在的數據庫、集合、輸出格式、導出列名文件位置和輸出文件名的格式,編寫好命令并運行就可以導出了:
1mongoexport?--db?ITjuzi?--collection?itjuzi_investevent?--type=csv?--fieldFile?C:\Users\sony\Desktop\fields.txt?--out?C:\Users\sony\Desktop\investevent.csv
cmd 命令:
導出 csv 結果如下:
Tips:直接用 excel 打開可能會是亂碼,需先用 Notepad++ 轉換為 UTF-8 編碼,然后 excel 再打開就正常了。
以上,我們就完成了整個數據表的爬取。
3.6. 完整代碼
下面,可以再嘗試爬取創業公司、投資機構和千里馬的數據。他們的數據結構形式是一樣的,只需要更換相應的參數就可以了,感興趣的話可以嘗試下。將上面的代碼再稍微整理一下,完整代碼如下:
?1importrequests
?2importre
?3importpymongo
?4importrandom
?5importtime
?6importjson
?7importrandom
?8importnumpyasnp
?9importcsv
10importpandasaspd
11fromfake_useragentimportUserAgent
12importsocket#?斷線重試
13fromurllib.parseimporturlencode
14#?隨機ua
15ua?=?UserAgent()
16#?mongodb數據庫初始化
17client?=?pymongo.MongoClient('localhost',27017)
18#?獲得數據庫
19db?=?client.ITjuzi
20#?獲得集合
21mongo_collection1?=?db.itjuzi_investevent
22mongo_collection2?=?db.itjuzi_company
23mongo_collection3?=?db.itjuzi_investment
24mongo_collection4?=?db.itjuzi_horse
25
26classitjuzi(object):
27def__init__(self):
28
29self.headers?=?{
30'User-Agent':?ua.random,
31'X-Requested-With':'XMLHttpRequest',
32#?主頁cookie
33'Cookie':'你的cookie',
34}
35self.url?='http://radar.itjuzi.com/investevent/info?'#?investevent
36#?self.url?=?'http://radar.itjuzi.com/company/infonew?'???????#?company
37#?self.url?=?'http://radar.itjuzi.com/investment/info?'???????#?investment
38#?self.url?=?'https://www.itjuzi.com/horse'???????????????#?horse
39self.session?=?requests.Session()
40
41defget_table(self,?page):
42"""
431?獲取投融資事件網頁內容
44"""
45params?=?{#?1?invsestevent
46'location':'in',
47'orderby':'def',
48'page':?page,
49'date':2018#年份??
50}
51
52#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?##?#?#?#?#?#?#?#?#?#?#?#
53#?params?=?{??????????????????#?2?company
54#?????'page':?page,
55#?????#?'scope[]':?1,??#?行業?1教育
56#?????'orderby':?'pv',
57#?????'born_year[]':?2018,??#?只能單年,不能多年篩選,會保留最后一個
58#?}
59#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?##?#?#?#?#?#?#?#?#?#?#?#
60#?params?=?{??????????????????#?3?investment
61#?'orderby':?'num',
62#?'page':?page
63#?}
64#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?#?##?#?#?#?#?#?#?#?#?#?#?#
65#?params?=?{??????????????????#?4?horse
66#?}
67#?可能會遇到請求失敗,則設置3次重新請求
68retrytimes?=3
69whileretrytimes:
70try:
71response?=?self.session.get(
72self.url,?params=params,?headers=self.headers,timeout?=?(5,20)).json()
73self.save_to_mongo(response)
74break
75exceptsocket.timeout:
76print('下載第{}頁,第{}次網頁請求超時'.format(page,retrytimes))
77retrytimes?-=1
78
79defsave_to_mongo(self,?response):
80try:
81data?=?response['data']['rows']#?dict可以連續選取字典層內的內容
82#?data?=response??#?爬取千里馬時需替換為此data
83df?=?pd.DataFrame(data)
84table?=?json.loads(df.T.to_json()).values()
85ifmongo_collection1.insert_many(table):#?investevent
86#?if?mongo_collection2.insert_many(table):????#?company
87#?if?mongo_collection3.insert_many(table):????#?investment
88#?if?mongo_collection4.insert_many(table):????#?horse?
89print('存儲到mongodb成功')
90sleep?=?np.random.randint(3,7)
91time.sleep(sleep)
92exceptException:
93print('存儲到mongodb失敗')
94
95defspider_itjuzi(self,?start_page,?end_page):
96forpageinrange(start_page,?end_page):
97print('下載第%s頁:'%?(page))
98self.get_table(page)
99print('下載完成')
100
101if__name__?=='__main__':
102spider?=?itjuzi()
103spider.spider_itjuzi(1,2)
源代碼也可以在下面的鏈接中獲取:
https://github.com/makcyun/web_scraping_with_python
4. 總結:
本文以桔子網為例,介紹了需登錄網站的爬取方法。即:先模擬登錄再爬取數據信息。但是還有一些網站登錄時需要輸入驗證碼,這讓爬取難度又增加,后期會再進行介紹。
該網站相比之前的爬蟲網站,反爬措施高了很多。本文通過設置隨機延時、隨機 UserAgent,可一定程度上增加爬蟲的穩定性。但是仍然會受到反爬措施的限制,后期可嘗試通過設置 IP 代理池進一步提升爬蟲效率。
上面的爬蟲程序在爬取過程容易中斷,接著再進行爬取即可。但是手動修改非常不方便,也容易造成數據重復爬取或者漏爬。所以,為了更完整地爬取,需增加斷點續傳的功能。
補充一下,后期可能會在我的博客中不斷更新、補充本文的內容。如想獲得更多,可點擊閱讀原文,或者瀏覽器打開我的博客鏈接。
https://www.makcyun.top
本文完。
作者好文推薦:分析了6000款App,竟有這么多佳軟神器沒用過
Python愛好者社區歷史文章大合集:
Python愛好者社區歷史文章列表(每周append更新一次)
福利:文末掃碼立刻關注公眾號,“Python愛好者社區”,開始學習Python課程:
關注后在公眾號內回復“課程”即可獲取:
小編的轉行入職數據科學(數據分析挖掘/機器學習方向)【最新免費】
小編的Python入門免費視頻課程!!!
小編的Python快速上手matplotlib可視化庫!!!
崔老師爬蟲實戰案例免費學習視頻。
陳老師數據分析報告制作免費學習視頻。
玩轉大數據分析!Spark2.X+Python 精華實戰課程免費學習視頻。
總結
以上是生活随笔為你收集整理的爬取国内创业公司、投资机构、独角兽公司信息的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 高性能计算机重要的配件,电脑配件大盘点,
- 下一篇: openGauss数据库客户端接入认证详