5行程式碼就能入門爬蟲?
作者 | 蘇克1900
來源 | 第2大腦(ID:Mocun6)
責編 | swallow
不少讀者是剛剛入門Python或者想學習Python的,今天就來談談如何用快速入門爬蟲。
先說結論:入門爬蟲很容易,幾行程式碼就可以,可以說是學習Python最簡單的途徑。
以我純小白、零基礎的背景來說,入門爬蟲其實很容易,容易在程式碼編寫很簡單,簡單的爬蟲通常幾行就能搞定,而不容易在確定爬蟲的目標,也就是說為什麼要去寫爬蟲,有沒有必要用到爬蟲,是不是手動操作幾乎無法完成,網際網路上有數以百萬千萬計的網站,到底以哪一個網站作為入門首選,這些問題才是難點。所以在動手寫爬蟲前,最好花一些時間想一想這清楚這些問題。
「Talk is cheap. Show me the code」,下面我就以曾寫過的一個爬蟲為例,說一說我是如何快速入門Python爬蟲的。
▌確立目標
第一步,確立目標。
為什麼想起寫這個爬蟲呢,是因為這是曾經在工作中想要解決的問題,當時不會爬蟲,只能用Excel花了數個小時才勉強地把資料爬了下來, 所以在接觸到爬蟲後,第一個想法就是去實現曾未實現的目標。以這樣的方式入門爬蟲,好處顯而易見,就是有了很明確的動力。
很多人學爬蟲都是去爬網上教程中的那些網站,網站一樣就算了,爬取的方法也一模一樣,等於抄一遍,不是說這樣無益,但是會容易導致動力不足,因為你沒有帶著目標去爬,只是為了學爬蟲而爬,爬蟲雖然是門技術活,但是如果能建立在興趣愛好或者工作任務的前提下,學習的動力就會強很多。
在確定好爬蟲目標後,接著我就在腦中預想了想要得到什麼樣的結果、如何展示出來、以什麼形式展現這些問題。所以,我在爬取網站之前,就預先構想出了想要的一個結果,大致是下面這張圖的樣子。
目標是利用爬下來的資料,嘗試從不同維度年份、省份、城市去分析全國的股市資訊,然後通過視覺化圖表呈現出來。
拋開資料,可能你會覺得這張圖在排版佈局、色彩搭配、字型文字等方面還挺好看的。這些呢,就跟爬蟲沒什麼關係了,而跟審美有關,提升審美的一種方式是可以通過做PPT來實現,所以你看,我們們說著說著就從爬蟲跳到了 PPT,不得不說我此前發的文章鋪墊地很好啊,哈哈。其實,在職場中,你擁有的技能越多越好。
▌直接開始
確定了目標後,第二步就可以開始寫爬蟲了,如果你像我一樣,之前沒有任何程式設計基礎,那我下面說的思路,可能會有用。
剛開始動手寫爬蟲,我只關注最核心的部分,也就是先成功抓到資料,其他的諸如:下載速度、儲存方式、程式碼條理性等先不管,這樣的程式碼簡短易懂、容易上手,能夠增強信心。
所以,我在寫第一遍的時候,只用了5行程式碼,就成功抓取了全部所需的資訊,當時的感覺就是很爽,覺得爬蟲不過如此啊,自信心爆棚。
1import pandas as pd
2import csv
3for i in range(1,178): # 爬取全部頁
4 tb = pd.read_html('http://s.askci.com/stock/a/?reportTime=2017-12-31&pageNum=%s' % (str(i)))[3]
5 tb.to_csv(r'1.csv', mode='a', encoding='utf_8_sig', hea
3000+ 上市公司的資訊,安安靜靜地躺在 Excel 中:
▌不斷完善
有了上面的信心後,我開始繼續完善程式碼,因為5行程式碼太單薄,功能也太簡單,大致從以下幾個方面進行了完善:
增加異常處理
由於爬取上百頁的網頁,中途很可能由於各種問題導致爬取失敗,所以增加了 try except 、if 等語句,來處理可能出現的異常,讓程式碼更健壯。
增加程式碼靈活性
初版程式碼由於固定了URL引數,所以只能爬取固定的內容,但是人的想法是多變的,一會兒想爬這個一會兒可能又需要那個,所以可以通過修改 URL 請求引數,來增加程式碼靈活性,從而爬取更靈活的資料。
修改儲存方式
初版程式碼我選擇了儲存到Excel這種最為熟悉簡單的方式,人是一種惰性動物,很難離開自己的舒適區。但是為了學習新知識,所以我選擇將資料儲存到 MySQL 中,以便練習 MySQL 的使用。
加快爬取速度
初版程式碼使用了最簡單的單程式爬取方式,爬取速度比較慢,考慮到網頁數量比較大,所以修改為了多程式的爬取方式。
經過以上這幾點的完善,程式碼量從原先的5行增加到了下面的幾十行:
1import requests
2import pandas as pd
3from bs4 import BeautifulSoup
4from lxml import etree
5import time
6import pymysql
7from sqlalchemy import create_engine
8from urllib.parse import urlencode # 編碼 URL 字串
9
10start_time = time.time() #計算程式執行時間
11def get_one_page(i):
12 try:
13 headers = {
14 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'
15 }
16 paras = {
17 'reportTime': '2017-12-31',
18 #可以改報告日期,比如2018-6-30獲得的就是該季度的資訊
19 'pageNum': i #頁碼
20 }
21 url = 'http://s.askci.com/stock/a/?' + urlencode(paras)
22 response = requests.get(url,headers = headers)
23 if response.status_code == 200:
24 return response.text
25 return None
26 except RequestException:
27 print('爬取失敗')
28
29def parse_one_page(html):
30 soup = BeautifulSoup(html,'lxml')
31 content = soup.select('#myTable04')[0] #[0]將返回的list改為bs4型別
32 tbl = pd.read_html(content.prettify(),header = 0)[0]
33 # prettify()優化程式碼,[0]從pd.read_html返回的list中提取出DataFrame
34 tbl.rename(columns = {'序號':'serial_number', '股票程式碼':'stock_code', '股票簡稱':'stock_abbre', '公司名稱':'company_name', '省份':'province', '城市':'city', '主營業務收入(201712)':'main_bussiness_income', '淨利潤(201712)':'net_profit', '員工人數':'employees', '上市日期':'listing_date', '招股書':'zhaogushu', '公司財報':'financial_report', '行業分類':'industry_classification', '產品型別':'industry_type', '主營業務':'main_business'},inplace = True)
35 return tbl
36
37def generate_mysql():
38 conn = pymysql.connect(
39 host='localhost',
40 user='root',
41 password='******',
42 port=3306,
43 charset = 'utf8',
44 db = 'wade')
45 cursor = conn.cursor()
46
47 sql = 'CREATE TABLE IF NOT EXISTS listed_company (serial_number INT(20) NOT NULL,stock_code INT(20) ,stock_abbre VARCHAR(20) ,company_name VARCHAR(20) ,province VARCHAR(20) ,city VARCHAR(20) ,main_bussiness_income VARCHAR(20) ,net_profit VARCHAR(20) ,employees INT(20) ,listing_date DATETIME(0) ,zhaogushu VARCHAR(20) ,financial_report VARCHAR(20) , industry_classification VARCHAR(20) ,industry_type VARCHAR(100) ,main_business VARCHAR(200) ,PRIMARY KEY (serial_number))'
48 cursor.execute(sql)
49 conn.close()
50
51def write_to_sql(tbl, db = 'wade'):
52 engine = create_engine('mysql+pymysql://root:******@localhost:3306/{0}?charset=utf8'.format(db))
53 try:
54 tbl.to_sql('listed_company2',con = engine,if_exists='append',index=False)
55 # append表示在原有表基礎上增加,但該表要有表頭
56 except Exception as e:
57 print(e)
58
59def main(page):
60 generate_mysql()
61 for i in range(1,page):
62 html = get_one_page(i)
63 tbl = parse_one_page(html)
64 write_to_sql(tbl)
65
66# # 單程式
67if __name__ == '__main__':
68 main(178)
69 endtime = time.time()-start_time
70 print('程式執行了%.2f秒' %endtime)
71
72# 多程式
73from multiprocessing import Pool
74if __name__ == '__main__':
75 pool = Pool(4)
76 pool.map(main, [i for i in range(1,178)]) #共有178頁
77 endtime = time.time()-start_time
78 print('程式執行了%.2f秒' %(time.time()-start_time))
雖然程式碼行數增加了不少,但是這個過程卻覺得很自然,因為每次修改都是針對一個小點,一點點去學,搞懂後新增進來,而如果讓我上來就直接寫出這幾十行的程式碼,我很可能就放棄了。
所以,你可以看到,入門爬蟲是有套路的,最重要的是給自己信心。
(本文僅代表作者觀點,轉載請聯絡原作者)
精彩推薦
推薦閱讀:
點選“閱讀原文”,開啟CSDN APP 閱讀更貼心。
相關文章
- 5 行程式碼就能入門爬蟲?行程爬蟲
- 爬蟲入門爬蟲
- 爬蟲程式十分鐘入門爬蟲
- Python爬蟲入門Python爬蟲
- 【爬蟲】python爬蟲從入門到放棄爬蟲Python
- python-爬蟲入門Python爬蟲
- 爬蟲(1) - 爬蟲基礎入門理論篇爬蟲
- 爬蟲入門(HTTP和HTTPS)爬蟲HTTP
- 爬蟲入門(字串相關)爬蟲字串
- 爬蟲入門基礎-Python爬蟲Python
- python3 爬蟲入門Python爬蟲
- Python爬蟲入門,8個常用爬蟲技巧盤點Python爬蟲
- 什麼是Python爬蟲?python爬蟲入門難嗎?Python爬蟲
- python爬蟲入門八:多程式/多執行緒Python爬蟲執行緒
- python爬蟲 之 BeautifulSoup庫入門Python爬蟲
- 三分鐘爬蟲入門爬蟲
- Python3爬蟲入門(一)Python爬蟲
- Python爬蟲入門【5】:27270圖片爬取Python爬蟲
- 為什麼學習python及爬蟲,Python爬蟲[入門篇]?Python爬蟲
- 帶你入門Python爬蟲,8個常用爬蟲技巧盤點Python爬蟲
- Python爬蟲入門【9】:圖蟲網多執行緒爬取Python爬蟲執行緒
- 爬蟲:多程式爬蟲爬蟲
- Python爬蟲入門教程 55-100 python爬蟲高階技術之驗證碼篇Python爬蟲
- Python爬蟲入門教程導航帖Python爬蟲
- Python3 爬蟲快速入門攻略Python爬蟲
- scrapy入門教程()部署爬蟲專案爬蟲
- Python網路爬蟲4 - scrapy入門Python爬蟲
- 爬蟲工程師的入門簡介爬蟲工程師
- 爬蟲工程師的unidbg入門教程爬蟲工程師
- 爬蟲入門第一章爬蟲
- Scrapy使用入門及爬蟲代理配置爬蟲
- python入門之爬蟲工具有哪些?Python爬蟲
- 爬蟲入門學習筆記3爬蟲筆記
- 04selenium爬蟲輕鬆入門爬蟲
- [雪峰磁針石部落格]python爬蟲cookbook1爬蟲入門Python爬蟲
- Python爬蟲入門教程 50-100 Python3爬蟲爬取VIP視訊-Python爬蟲6操作Python爬蟲
- 不用寫程式碼的爬蟲爬蟲
- 如何爬取視訊的爬蟲程式碼原始碼爬蟲原始碼