查看原文
其他

工具&方法丨学经济学也要敲代码——经生小白自力更生收集数据

Wallace 数据Seminar 2021-06-03

前言

我叫 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'# 初始urlroot_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实例)

工具&方法丨菜鸟升级打怪系列之python代码优化(1)

工具&方法 | 小刘老师“再”出新招:JSON数据转为面板数据


听说你还在为数据呈现烦恼?看这里!

数据呈现丨手把手教你如何利用Python绘制词云(内含代码)

数据呈现丨好用易懂的matplotlib可视化,快来了解一下!

数据呈现丨想要数据可视化?你还少了它!

数据呈现 | Stata+R+Python:拨开数据迷雾,窥探可视化之“美”(工具书推荐,附PDF资源链接)

数据呈现 |Stata+R+Python:一文帮你解决Paper、PPT中的数据可视化问题


让我猜猜,或许你需要的还有这些!

特别推荐丨老姚专栏:经典变量误差与衰减偏误:一个新的案例

特别推荐丨老姚专栏:多重共线性问题应该这样理解才对

学术前沿丨机器学习能成为因果推断的“圣杯”吗?

学术前沿 | 规律与因果:大数据对社会科学研究冲击之反思

特别推荐 | 专利引用数据,可以用来做哪些研究?





数据Seminar

这里是大数据、分析技术与学术研究的三叉路口



作者:Wallace审阅:Dyson编辑:青酱




    欢迎扫描👇二维码添加关注    


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存