工具&方法丨学经济学也要敲代码——经生小白自力更生收集数据
前言
我叫 Wallace ,目前就读于杭州某省属高校,半年前"入坑"经济学专业。经过指导老师半年的洗脑教导,我终于接受了如下事实:“在我们分析经济现象时,往往需要收集清理大量数据,特别是”新鲜活络“的互联网大数据,而python恰好能帮助我们规范(快速)爬取网站的数据。(what? 我是不是填错志愿进入经济统计?)”
于是,在完成专业要求的课程学习之外,上学期我被逼着邀请参加导师(多次下意识反复确认之后,确信导师和我都在经济学专业而不是经济统计专业学习/任课)主持的大数据开发创业公司的python爬虫培训。仗着本人自以为不错的数学功底和逻辑思维能力(是的,我超棒!),我还是撑到了最后。
猜猜哪个是我👆
暑假是我们几个学员正式发挥的时候。我的第一个爬虫任务是,(友好地)爬取海关网站的部分月度统计数据,并对杂乱的html文件按照文件名进行分类。这篇文章记录了我在第一次爬虫实战中的经历和心得体会。特别推荐给非专业出身的爬虫"小白"们,任何技术问题,都是"纸老虎"!
数据概览与总体思路
下图是需要爬取的月度进出口统计数据,一共有11页103个条目,而每个条目中都包含了一张表格。总的思路是,先写出爬取单个页面的代码,再通过chrome内核进行连续爬虫,最后保存进csv文件中。
#调用所需要的库
import pandas as pd
import requests
import os
html=requests.get('http://www.customs.gov.cn/customs/302249/302274/302278/302280/2546702/index.html') #向目标网站发起请求
df = pd.read_html(html.text,skiprows=3)[-1] # 取返回列表中的最后一个表格
df.columns = ['Year&Month', 'Total', ' Export', ' Import', 'Balance',
'1to12 total','1to12 export','1to12 import','1to12 balance']
print(df)
左右滑动查看更多
在上述代码中,skiprows的作用就是在爬取表格的时候把不需要的行给去掉。我们需要的内容是下图方框内的数据,因此要把表格的前三行给去掉,所以这里的skiprows=3。
那么,如何将爬取的数据保存到csv文件呢?
df.to_csv(r'E:\月度数据.csv',encoding='utf_8_sig', mode='a', sep=",", header=not os.path.exists(r'E:\月度数据.csv'),index=False)
左右滑动查看更多
在技术部大佬的指导下,通过上述代码即可把所获取的数据保存到csv文件。
to_csv()是DataFrame类的方法,header决定了是否保留列名。如果我们要输出的文件存在,即not os.path.exists(r'E:\月度数据.csv')为False,就不保存DataFrame的header。
此处需要注意编码方式:encoding='utf_8_sig',刚开始我采用的编码方式是encoding='utf-8',excel打开输出的csv结果为乱码,是因为excel需要BOM来识别'utf-8'的文件,所以将'utf_8'改为'utf_8_sig'后就不会出现乱码的情况了。
utf-8以字节为编码单元,它的字节顺序在所有系统中都是一样的,没有字节序的问题,也因此它实际上并不需要BOM(“ByteOrder Mark”), 但是utf-8 with BOM即utf_8_sig需要提供BOM("ByteOrder Mark")。
接下来可以采用selenium进行爬虫。
一、准备工作
在爬虫之前,我们要先做一些准备工作。
首先,在命令行当中安装selenium框架,安装步骤非常简单,命令为:pip install selenium
这是已经安装完成的显示。
接着,我们要下载安装浏览器的驱动ChromeDriver,因为selenium就是像用户一样去操作浏览器,是需要浏览器的驱动的。
下载链接:https://sites.google.com/a/chromium.org/chromedriver/downloads
输入浏览器内核路径:
engine_path = r'D:/Users/hong/Desktop/chromedriver_win32.exe'
左右滑动查看更多
然后,我们调用所需要的第三方库,并且调用浏览器
import selenium.webdriver as webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
import time
import traceback
import codecs
import re
import pandas as pd
import random
import os
import requests
左右滑动查看更多
如果没有安装这些库,则需要手动安装一下,代码为pip install + 库
的名称
二、选择元素
完成以上准备工作,我们可以正式进入正题了,再提醒下,任务是爬取海关总署网站上月度数据部分的所有表格内容。
首先我们通过F12查看网站的HTML代码,然后点击页面元素选择按钮,接着点击需定位的元素,最后查看定位元素的源代码。具体流程如下图所示。
通过上图的流程,我们可以通过Xpath定位页面中的标签
page_xpath = '//*[@id="708ff4f3b78e4b29a3b73c4fe3b64f3a"]'
左右滑动查看更多
用同样的方法可以获得第一行条目的位置:
row_xpath = '//*[@id="708ff4f3b78e4b29a3b73c4fe3b64f3a"]/div/ul/li[1]/a'
左右滑动查看更多
第二行条目:
row_xpath = '//*[@id="708ff4f3b78e4b29a3b73c4fe3b64f3a"]/div/ul/li[2]/a'
左右滑动查看更多
后面几行的row_xpath也是通过这种方式获得,我们可以发现每一行row_xpath存在规律,即只有li[]中的数字会随行数发生变化,因此可以利用format()写出row_xpath的通式:
row_xpath = '//*[@id="708ff4f3b78e4b29a3b73c4fe3b64f3a"]/div/ul/li[{}]/a'.format(row_num)
左右滑动查看更多
接着就可以定位到该元素:
element_list = driver.find_elements_by_xpath(row_xpath)
左右滑动查看更多
三、页面操作
在定位到页面的元素之后,我们要对该元素进行一些操作,这里需要去点击每一行和“下一页”按钮,鼠标左击代码如下。
driver.find_element_by_xpath(row_xpath).click() #点击进入详情页
driver.switch_to.window(driver.window_handles[-1]) #点击每一行的详情页后都会弹出新的一页,所以需要进行窗口切换到弹出页
driver.find_element_by_xpath(page_xpath).click() #点击下一页翻页
左右滑动查看更多
四、设置等待时间
为了保证程序运行的稳定性,我们需要添加等待时间。
我们采用WebDriverWait()的方法,即在设规定的时间内,默认每隔一段时间检测一次当前页面元素是否存在,如果超出规定时间还未检测到页面元素则报错。
bool_func = lambda x: driver.find_elements_by_xpath(page_xpath)
webdriver.support.wait.WebDriverWait(driver, 20).until(bool_func)
#确定需要的页面打开完毕,规定时间为20秒
左右滑动查看更多
五、其它操作
除了上述四个重要的步骤,我们还会用到一些关于页面和标题的操作。
title = driver.title #获取网页标题
driver.get(root_url)#请求页面
print(driver.current_url) #输出当前的url
driver.close()#关闭页面
driver.quit()#关闭浏览器
左右滑动查看更多
六、完整代码
import selenium.webdriver as webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
import time
import traceback
import codecs
import re
import pandas as pd
import random
import os
import requests
# 浏览器内核路径
engine_path = r'D:/Users/hong/Desktop/chromedriver_win32.exe'
# 初始url
root_url = 'http://www.customs.gov.cn/eportal/ui?pageId=302280¤tPage=5&moduleId=708ff4f3b78e4b29a3b73c4fe3b64f3a&staticRequest=yes'
#配置虚拟浏览器
options = webdriver.ChromeOptions()
options.add_argument("--headless")
driver = webdriver.Chrome(executable_path=engine_path, options=options)
driver.set_window_size(1920, 1080) # 主要为了方便做屏幕截图
driver.get(root_url)
page_xpath = '//*[@id="708ff4f3b78e4b29a3b73c4fe3b64f3a"]' #从网页中获取页面的xpath
bool_func = lambda x: driver.find_elements_by_xpath(page_xpath)
webdriver.support.wait.WebDriverWait(driver, 20).until(bool_func)
row_num = 1
page_num = 1 #从第一页第一行开始
num = 1
while True:
page_xpath = '//*[@id="708ff4f3b78e4b29a3b73c4fe3b64f3a"]'
bool_func = lambda x: driver.find_elements_by_xpath(page_xpath)
webdriver.support.wait.WebDriverWait(driver, 20).until(bool_func)
row_xpath = '//*[@id="708ff4f3b78e4b29a3b73c4fe3b64f3a"]/div/ul/li[{}]/a'.format(row_num)#每一行的xpath都带有规律
element_list = driver.find_elements_by_xpath(row_xpath)
if element_list:
element_list[0].click() #点击进入详情页
driver.switch_to.window(driver.window_handles[-1]) #浏览器中,进入详情页要翻页,所以要更换浏览器标签页。
# 确定我们需要的页面打开完毕
bool_func = lambda x: driver.find_elements_by_id('easysiteText')
webdriver.support.wait.WebDriverWait(driver, 20).until(bool_func)
title = driver.title
html = driver.page_source
df = pd.read_html(html.text,skiprows=3)[-1] # 取返回列表中的最后一个表格
df.columns = ['Year&Month', 'Total', ' Export', ' Import', 'Balance',
'1to12 total', '1to12 export', '1to12 import', '1to12 balance']
df.to_csv(r'E:/{}{}.csv'.fromat(title,random.randint(1,10)),encoding='utf_8_sig', mode='a', sep=",",index=False)
time.sleep(1)
print(num)
print(driver.current_url)
driver.close()
driver.switch_to.window(driver.window_handles[-1])
num = num + 1
row_num = row_num + 1
else:
page_xpath = '//*[@id="708ff4f3b78e4b29a3b73c4fe3b64f3a"]/div/div/div[1]/a[3]' #下一页的xpath
driver.find_element_by_xpath(page_xpath).click() #点击下一页翻页
row_num = 1
page_num = page_num + 1
左右滑动查看更多
以上就是通过selenium方法爬取网页的代码,简而言之有如下三大步骤:
1、构造url;
2、使用 selenuim 库控制浏览器访问url;
3、页面加载完成后提取响应数据。
推荐selenium学习网站:
https://blog.csdn.net/xie_0723/article/details/51437650
https://blog.csdn.net/aman1111/article/details/82049739
结语
以上就是经生小白Wallace用python爬取海关总署数据并分类的内容。
虽然之前受过爬虫的培训,但是听大佬们培训和轮到自己亲手实操完全是两种不同的心境,有时我所想的流程框架却不能用代码来实现(其实就是水平不够啦),在爬虫的过程中主要让我头痛的是正则表达式的书写和xpath的定位,还有一些让人摸不着头脑的报错。
随着对爬虫不断的学习和实践,我也越发感觉爬虫并不是件简单的事,同时python中还有很多值得我去发掘的模块。记得小刘老师曾经说过:“python主要是多练,光看视频不亲手操作是没有用的。”不积跬步无以至千里,经生小白Wallace一定会努力成为一名富有实战经验的经济学专业学者!
你要的工具&方法我都给你整理好了!
工具&方法 | 6张图,3分钟阅读即可掌握stata全部命令
工具&方法 | 10个Python Pandas小技巧让你的工作更高效(附代码实例)
工具&方法 | 6行代码教你用python做OLS回归(内附CFPS实例)
工具&方法 | 小刘老师“再”出新招:JSON数据转为面板数据
听说你还在为数据呈现烦恼?看这里!
数据呈现丨手把手教你如何利用Python绘制词云(内含代码)
数据呈现丨好用易懂的matplotlib可视化,快来了解一下!
数据呈现 | Stata+R+Python:拨开数据迷雾,窥探可视化之“美”(工具书推荐,附PDF资源链接)
数据呈现 |Stata+R+Python:一文帮你解决Paper、PPT中的数据可视化问题
让我猜猜,或许你需要的还有这些!
数据Seminar
这里是大数据、分析技术与学术研究的三叉路口
欢迎扫描👇二维码添加关注