excel抓取多页网页数据(东方财富网财务报表10年近百万行财务报表数据学习方法(组图))
优采云 发布时间: 2022-03-20 20:08excel抓取多页网页数据(东方财富网财务报表10年近百万行财务报表数据学习方法(组图))
本文转载自以下网站:50行代码爬取东方财富网上市公司近百万行财务报表数据10年
主要学习地点:
1.分析网站的ajax请求信息
2.构造参数
3.发起请求后处理获取到的数据
4.保存表单
重点:分析表单类网站的ajax请求,以及如何保存这类信息(关于表单)
通过分析 URL 的 JavaScript 请求,它可以以比 Selenium 快 100 倍的方法快速爬取东方财富网历年各上市公司的财务报表数据。
摘要:在上一篇文章中,我们成功使用Selenium爬取了东方财富网的财务报表数据,但是速度很慢。爬取 70 个页面需要几十分钟。为了加快速度,本文分析网页的JavaScript请求,找到数据接口,然后快速爬取财务报表数据。
1. JavaScript 请求分析
在上一篇文章文章中,我们简单的划分了东方财富网财务报表网页后台的js请求,文章回顾:()
接下来,我们向下钻取。首先,点击报告底部的 Next Page,然后观察左侧的 Name 列,看看弹出了哪些新请求:
可以看到,连续点击下一页时,会弹出get?以类型开头的请求。点击右侧的Headers选项卡,可以看到请求的URL,URL很长,暂时忽略,后面会分析参数。然后,点击右侧的Preview and Response,可以看到里面有很多整齐的数据。试着猜测这可能是财务报表中的数据。和表格对比后发现,这正是我们需要的数据,太好了。
然后将URL复制到新链接并打开,可以看到表格中的数据显示完美。可以在不添加Headers和UA请求的情况下获取。看来东方财富网是很慷慨的。
至此,爬取思路就很清晰了。首先使用Request请求URL,对获取的数据进行正则匹配,将数据转换成json格式,然后写入本地文件,最后添加分页循环进行爬取。这比以前的 Selenium 简单得多,并且应该快很多倍。我们先尝试爬取一页数据来看看。
2. 爬取单页2.1. 爬取分析
这里我们还是以2018年中报的利润表为例,抓取网页表格数据的第一页,网页url为:
表格第一页js请求的url为:%20spmVUpAF={pages:(tp),data:%20(x)}&filter=(reportdate=^2018-06-30^)&rt=51312886,数据:%20 (x)}&filter=(reportdate=^2018-06-30^)&rt=51312886)
接下来,我们通过分析 url 来抓取表格内容。
import requests
def get_table():
params = {
'type': 'CWBB_LRB',
这里我们定义了一个get_table()方法来输出抓取到的表格第一页的内容。params 是 url 请求中收录的参数。
这里简单说明一下重要参数:type是7个表的类型说明,type分为'CWBB_'和'LRB'、资产负债表等两部分。最后3个表以'CWBB_开头',以及绩效报告到前4个表格,如任命披露时间表,以'YJBB20_'开头;“LRB”是损益表的首字母缩写词,同样,绩效表是“YJBB”。所以,如果要爬取不同的表,就需要改变type参数。'filter'是表格过滤参数,其中过滤掉了中报的数据。不同的表过滤条件会有所不同,所以当类型类型改变时,过滤器类型也要相应修改。
设置好params参数后,将url和params参数传入requests.get()方法,这样请求连接就构建好了。几行代码就可以成功获取网页首页的表格数据:
可以看到,表信息存放在LFtlXDqn变量中,pages表示该表有72页。data是表数据,它是一个由多个字典组成的列表,每个字典是表中的一行数据。我们可以通过正则表达式分别提取页面和数据数据。
2.2. 正则表达式抽取表
这里使用 \d+ 匹配页数中的值,然后使用 re.search() 方法进行提取。group(1) 表示输出第一个结果,这里是()中的页数。
这里用(.*)来匹配表数据,表示贪婪匹配,因为数据中有很多字典,每个字典都以'}'结尾,所以我们使用贪婪匹配到最后一个'}',以便获取数据 所有数据。在大多数情况下,我们可能会使用 (.*?),表示非贪婪匹配,即最多匹配一个 '}'。在这种情况下,我们只能匹配第一行数据,这显然是错误的。
2.3. json.loads() 输出形式
这里提取的列表是str字符类型,我们需要将其转换为list列表类型。为什么要把它转成list类型,因为不能用操作list的方法来操作str,比如list slice。转换为列表后,我们可以对列表进行切片。例如data[0]可以获取第一个{}中的数据,也就是表格的第一行,方便后续构建循环逐行输出表格数据。这里使用 json.loads() 方法将 str 转换为 list。
接下来我们将表格内容输入到 csv 文件中。
通过for循环,依次取出表中的每一行字典数据{},然后使用with...open方法写入'eastmoney.csv'文件。
Tips:“a”表示可重写;encoding='utf_8_sig' 可以防止csv文件中的汉字出现乱码;换行为空,以避免每行数据出现空行。
这样第一页50行的表格数据就成功输出到了csv文件中:
在这里,我们还可以在输出表之前添加一个表头:
这里data[0]表示列表的字典中的数据,data[0].keys()表示获取字典中的key值,即列标题。在外面添加一个列表序列化(结果如下),然后将列表输出到'eastmoney.csv'作为表的列标题。
['scode', 'hycode', 'companycode', 'sname', 'publishname', 'reporttimetypecode', 'combinetypecode', 'dataajusttype', 'mkt', 'noticedate', 'reportdate', 'parentnetprofit', 'totaloperatereve', 'totaloperateexp', 'totaloperateexp_tb', 'operateexp', 'operateexp_tb', 'saleexp', 'manageexp', 'financeexp', 'operateprofit', 'sumprofit', 'incometax', 'operatereve', 'intnreve', 'intnreve_tb', 'commnreve', 'commnreve_tb', 'operatetax', 'operatemanageexp', 'commreve_commexp', 'intreve_intexp', 'premiumearned', 'premiumearned_tb', 'investincome', 'surrenderpremium', 'indemnityexp', 'tystz', 'yltz', 'sjltz', 'kcfjcxsyjlr', 'sjlktz', 'eutime', 'yyzc']
44
以上就完成了单页表单的爬取下载到本地的过程。
3. 多页表单爬取
将上面的代码整理成对应的函数,然后添加一个for循环。只需50行代码就可以爬取72页的利润报告数据:
import requests
import re
import json
import csv
import time
def get_table(page):
params = {
'type': 'CWBB_LRB',
整个下载只用了20多秒,之前用selenium要几十分钟,效率提升了100倍!
在这里,如果我们要下载所有时期(2007 年到 2018 年)的利润表数据,也很简单。只要将type中的filter参数注释掉,即不过滤日期,则可以下载所有时段的数据。在这里,当我们取消过滤栏的注释时,我们会发现page_all的总页数会从2018年中报的72页增加到2528页。全部下载完成后,表有12万多行数据。基于这些数据,你可以尝试从中做一些有价值的数据分析。
4. 通用代码结构
以上代码实现了对2018年中期利润报告的爬取,但如果不想局限于本报告,还想爬取其他报告或任何时期的其他数据,则需要手动修改代码,很不方便。方便。所以上面的代码可以说很短但不够强大。
为了能够灵活的爬取任意类别、任意时期的报表数据,需要对代码进行一些处理,进而构建出通用的强大爬虫程序。
"""
e.g: http://data.eastmoney.com/bbsj/201806/lrb.html
"""
import requests
import re
from multiprocessing import Pool
import json
import csv
import pandas as pd
import os
import time
以爬取2018年中业绩报告为例,感受一下比selenium快很多的爬取效果(视频链接):
使用上述程序,我们可以下载任何时期的数据和任何报告。在这里,我下载并完成了2018年中报中所有7个报表的数据。
文中的代码和素材资源可以从以下链接获取: