背景
深圳证券业协会网站公布了辖区内所有证券营业部的股基交易量、净利润、营收数据,免登录就能查看,我们需要获取这部分数据,由于都是pdf文件,所以首先得爬虫获取pdf文件到本地然后对pdf文件进行解析和数据处理。 网页链接
抓包
抓包的实例我之前的文章介绍了很多次了。 这回我直接把找到需要的参数展示一下:
data = {'typeid':18,'pagesize':40,'pageno':1}
导入第三方库
import pandas as pd
import requests
import json
import time
import os
import pdfplumber as pdf
import re
import numpy as np
爬虫代码
简简单单用个requests.post方法就行了,就是这么朴实无华。
def SZ_spyder(flv):
lp_url='http://www.cncapital.net/szsa/archives/list/1.0'
headers={ "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"Accept-Encoding":"gzip, deflate",
"Accept-Language":"zh-CN,zh;q=0.9",
"Host":"www.cncapital.net",
"User-Agent":"xxx"
}
data = {'typeid':18,'pagesize':40,'pageno':1}
req = requests.post(lp_url,data=data,headers=headers)
time.sleep(2)
r = json.loads(req.text)
clist=r['data']
tlist=[]
for i in clist:
id = i['id']
title=i['title']
data2 = {'id':id}
if title not in flv:
tlist.append(title+'.pdf')
req2 = requests.post(lp_url,data=data2,headers=headers)
time.sleep(1)
r2 = json.loads(req2.text)
fff = r2['attachment'][0]['url']
print(fff)
pdf_url = 'http:'+fff
file = requests.get(pdf_url,headers=headers)
time.sleep(1)
file_path='D:xxx'+title+'.pdf'
f = open(file_path,'wb')
f.write(file.content)
f.close()
else:
continue
return tlist
下回还可以讲讲接口测试,如何通过api上传文件。
pdf解析
这里我们还是用pdfplumber,安装什么的就不讲了。 一个pdf文件由三个表格组成,分别展示净利润、营收和交易量,这个任务很麻烦的点就在于不同时间的文件,三种数据展示前后顺序不一致,这就给数据结构化处理添麻烦,我只能用笨方法解决,就是多加if语句。
def read_pdf(p_num,pf,mm):
df_trd = pd.DataFrame(columns=['dpm_nm','value'])
df_inc = pd.DataFrame(columns=['dpm_nm','value'])
df_prf = pd.DataFrame(columns=['dpm_nm','value'])
pnn=p_num-1
pn_list=list(range(p_num))
if int(mm)>=20210601:
ll = [0,3,4]
else :
ll = [0,1,2]
for j in pn_list :
pp = pf.pages[j]
t = pp.extract_table()
dp = pd.DataFrame(t[1:],columns=t[0])
if len(list(dp.columns))>3:
dpp = dp.iloc[:,ll].set_axis(['dpm_nm','当月排序','value'],axis='columns')
dpp['dt']=mm
else:
dpp = dp.iloc[:,:3].set_axis(['当月排序','dpm_nm','value'],axis='columns')
dpp['dt']=mm
fdf = dpp[['dpm_nm','value','dt']]
df_trd = pd.concat([df_trd,fdf],axis=0)
pnn=pnn-1
print('交易额:第'+str(j)+'页')
if dpp['dpm_nm'].iloc[-1]!='合计' and dpp['dpm_nm'].iloc[-1]!='':
continue
else:
k=j+1
for k in pn_list[j+1:]:
pp = pf.pages[k]
t = pp.extract_table()
dp = pd.DataFrame(t[1:],columns=t[0])
if len(list(dp.columns))>3:
dpp = dp.iloc[:,:3].set_axis(['dpm_nm','当月排序','value'],axis='columns')
dpp['dt']=mm
else:
dpp = dp.iloc[:,:3].set_axis(['当月排序','dpm_nm','value'],axis='columns')
dpp['dt']=mm
fdf = dpp[['dpm_nm','value','dt']]
df_inc = pd.concat([df_inc,fdf],axis=0)
pnn=pnn-1
print('收入:第'+str(k)+'页')
if dpp['dpm_nm'].iloc[-1]!='合计' and dpp['dpm_nm'].iloc[-1]!='':
continue
else:
l=k+1
for l in pn_list[k+1:]:
pp = pf.pages[l]
t = pp.extract_table()
dp = pd.DataFrame(t[1:],columns=t[0])
if len(list(dp.columns))>3:
dpp = dp.iloc[:,:3].set_axis(['dpm_nm','当月排序','value'],axis='columns')
dpp['dt']=mm
fdf = dpp[['dpm_nm','value','dt']]
df_prf = pd.concat([df_prf,fdf],axis=0)
pnn=pnn-1
print('净利润:第'+str(l)+'页')
elif len(list(dp.columns))>1:
dpp = dp.iloc[:,:3].set_axis(['当月排序','dpm_nm','value'],axis='columns')
dpp['dt']=mm
fdf = dpp[['dpm_nm','value','dt']]
df_prf = pd.concat([df_prf,fdf],axis=0)
pnn=pnn-1
print('净利润:第'+str(l)+'页')
else:
break
break
break
return df_trd,df_inc,df_prf
完整代码
我把代码放在了GitHub上. 但我其实平时懒得上GitHub,作为一名非职业的程序猿,我表示CSDN就够用了。 有问题请私信。
|