作者 | 苏克1900 来源 | 第2大脑(ID:Mocun6) 责编 | swallow 不少读者打开凤凰新闻,查看更多高清图片
作者 | 苏克1900
来源 | 第2大脑(ID:Mocun6)
责编 | swallow
不少读者是刚刚入门Python或者想学习Python的,今天就来谈谈如何用快速入门爬虫。
先说结论:入门爬虫很容易,几行代码就可以,可以说是学习Python最简单的途径。
以我纯小白、零基础的背景来说,入门爬虫其实很容易,容易在代码编写很简单,简单的爬虫通常几行就能搞定,而不容易在确定爬虫的目标,也就是说为什么要去写爬虫,有没有必要用到爬虫,是不是手动操作几乎无法完成,互联网上有数以百万千万计的网站,到底以哪一个网站作为入门首选,这些问题才是难点。所以在动手写爬虫前,最好花一些时间想一想这清楚这些问题。
「Talk is cheap. Show me the code」,下面我就以曾写过的一个爬虫为例,说一说我是如何快速入门Python爬虫的。
▌确立目标
第一步,确立目标。
为什么想起写这个爬虫呢,是因为这是曾经在工作中想要解决的问题,当时不会爬虫,只能用Excel花了数个小时才勉强地把数据爬了下来, 所以在接触到爬虫后,第一个想法就是去实现曾未实现的目标。以这样的方式入门爬虫,好处显而易见,就是有了很明确的动力。
很多人学爬虫都是去爬网上教程中的那些网站,网站一样就算了,爬取的方法也一模一样,等于抄一遍,不是说这样无益,但是会容易导致动力不足,因为你没有带着目标去爬,只是为了学爬虫而爬,爬虫虽然是门技术活,但是如果能建立在兴趣爱好或者工作任务的前提下,学习的动力就会强很多。
在确定好爬虫目标后,接着我就在脑中预想了想要得到什么样的结果、如何展示出来、以什么形式展现这些问题。所以,我在爬取网站之前,就预先构想出了想要的一个结果,大致是下面这张图的样子。
目标是利用爬下来的数据,尝试从不同维度年份、省份、城市去分析全国的股市信息,然后通过可视化图表呈现出来。
抛开数据,可能你会觉得这张图在排版布局、色彩搭配、字体文字等方面还挺好看的。这些呢,就跟爬虫没什么关系了,而跟审美有关,提升审美的一种方式是可以通过做PPT来实现,所以你看,咱们说着说着就从爬虫跳到了 PPT,不得不说我此前发的文章铺垫地很好啊,哈哈。其实,在职场中,你拥有的技能越多越好。
▌直接开始
确定了目标后,第二步就可以开始写爬虫了,如果你像我一样,之前没有任何编程基础,那我下面说的思路,可能会有用。
刚开始动手写爬虫,我只关注最核心的部分,也就是先成功抓到数据,其他的诸如:下载速度、存储方式、代码条理性等先不管,这样的代码简短易懂、容易上手,能够增强信心。
所以,我在写第一遍的时候,只用了5行代码,就成功抓取了全部所需的信息,当时的感觉就是很爽,觉得爬虫不过如此啊,自信心爆棚。
1import pandas as pd2import csv3for i in range(1,178): # 爬取全部页4 tb = pd.read_html(?reportTime=2017-12-31&pageNum=%s % (str(i)))[3] 5 tb.to_csv(r1.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 字符串 910start_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.3615 }16 paras = {17 reportTime: 2017-12-31,18 #可以改报告日期,比如2018-6-30获得的就是该季度的信息19 pageNum: i #页码20 }21 url = ? + urlencode(paras)22 response = requests.get(url,headers = headers)23 if response.status_code == 200:24 return response.text25 return None26 except RequestException:27 print(爬取失败)2829def 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中提取出DataFrame34 tbl.rename(columns = {序号:serial_number, 股票代码:stock_code, 股票简称:stock_abbre, 公司名称:company_name, 省份:province, 城市:city, 主营业务收入():main_bussiness_income, 净利润():net_profit, 员工人数:employees, 上市日期:listing_date, 招股书:zhaogushu, 公司财报:financial_report, 行业分类:industry_classification, 产品类型:industry_type, 主营业务:main_business},inplace = True)35 return tbl3637def 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()4647 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()5051def 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)5859def 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)6566# # 单进程67if __name__ == __main__: 68 main(178)69 endtime = time.time()-start_time70 print(程序运行了%.2f秒 %endtime)7172# 多进程73from multiprocessing import Pool74if __name__ == __main__:75 pool = Pool(4)76 pool.map(main, [i for i in range(1,178)]) #共有178页77 endtime = time.time()-start_time78 print(程序运行了%.2f秒 %(time.time()-start_time))
虽然代码行数增加了不少,但是这个过程却觉得很自然,因为每次修改都是针对一个小点,一点点去学,搞懂后添加进来,而如果让我上来就直接写出这几十行的代码,我很可能就放弃了。
所以,你可以看到,入门爬虫是有套路的,最重要的是给自己信心。
(本文仅代表作者观点,转载请联系原作者)
精彩推荐
推荐阅读:
对标Bert?刷屏的GPT 2.0意味着什么
一次性掌握机器学习基础知识脉络 | 公开课笔记
Python助你抢红包
3分钟实现9种经典排序算法的可视化|Python
骗局翻新, 暗网活跃度倍增, 2018加密货币犯罪报告敢看吗?
云漫圈 | 学Python还是Java, 8张漫画带你全面分析
35 岁程序员,年后第一天被辞退
手机辐射排行榜:小米、一加远超 iPhone;阿里开工彩票最高奖金 1000 万;苹果再遭集体诉讼
2月报告:Python逆袭成功?踢馆Java,碾压C++!
点击“阅读原文”,打开CSDN APP 阅读更贴心。