26

爬虫 | 批量采集证券从业人员基本信息

 3 years ago
source link: https://mp.weixin.qq.com/s?__biz=MzI1MTE2ODg4MA%3D%3D&%3Bmid=2650075623&%3Bidx=1&%3Bsn=4cceede204060659b05ef8d22dfde0c2
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

腾讯课堂 | Python网络爬虫与文本分析(戳一戳)~~

f2mYFrv.png!mobile

采集中国证券业协会中某证券公司的从业人员信息。

  • 证券业协会网址 https://exam.sac.net.cn/pages/registration/sac-publicity-report.html

爬虫设计思路

证券业协会网站很特别

  1. 访问页面的方法的时候网址栏不变

  2. 打开开发者工具后,刷新或者翻页网址也不变

这种网页采用的是POST访问,访问方法如下

使用requests.post(url, data, headers, cookies, verify=False)

  • url 必用参数 页面对应的网址

  • param 网址具体参数,字典类型

  • headers 浏览器伪装头, 字典类型

  • cookies 浏览器的cookies, 字典类型

  • verify 是否需要验证,布尔类型

对付这类网站,设计爬虫流程

爬虫设计阶段 类型 问题 需要做到 1 网址分析 找到网页数据对应的网址规律 使用开发者工具network面板 2 访问 如何获取网页数据? 尝试使用requests的post方法访问一个url,拿到一个页面数据 3 解析 定位需要的数据 pyquery、json库解析数据 4 存储 如何存储数据 使用csv库将数据存储到csv文件中; 或者使用pandas库 5 整理 重复2-4 for循环对所有的url进行访问解析存储

今天我们爬安信证券从业人员的信息

https://exam.sac.net.cn/pages/registration/sac-publicity-report.html

rqaiimU.jpg!mobile

1. 网址分析

首先点击上图红色框,会打开新的页面。

https://exam.sac.net.cn/pages/registration/sac-publicity-finish.html?aoiId=1999145

a6b2y2A.png!mobile

MzEj2ii.png!mobile

现在页面的网址 https://exam.sac.net.cn/pages/registration/sac-publicity-finish.html?aoiId=1999145 中的 1999145 就是安信证券对应的id 。

所以后续如果想采集其他证券公司的从业信息,只需要更改aoiId就可以。

该公司员工很多,有55个页面,我们需要点翻页按钮,查看网址变化规律。

buMBZja.jpg!mobile

经查,访问该网站确为post请求方法。

aQreeim.jpg!mobile

2. 访问

post方法请求该网站时,需要的data参数如上图,需要手动构造出data字典。可以看到data参数中有

  • filter_EQS_AOI_ID :证券企业的id

  • page.pageSize: 每页显示多少个员工,默认100

  • page.pageNo: 当前页面数

现在我们访问安信证券

  • 该公司id为1999082

  • 只拿第一页, page.pageNo为1

import requests

url = 'https://exam.sac.net.cn/pages/registration/train-line-register!list.action'

data = {'filter_EQS_AOI_ID': '1999082',
'filter_EQS_PTI_ID': 0,
'page.searchFileName': 'homepage',
'page.sqlKey': 'PAGE_FINISH_PUBLICITY',
'page.sqlCKey': 'SIZE_FINISH_PUBLICITY',
'_search': 'false',
'page.pageSize': 100,
'page.pageNo': 1,
'page.orderBy': 'id',
'page.order': 'desc'}

resp = requests.post(url, data=data, verify=False)
resp
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/urllib3/connectionpool.py:1004: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,





<Response [200]>

返回response中含有200状态码,大概率访问成功了。现在查看一下数据, 使用resp.text


resp.text[:500]
'{"autoCount":true,"class":"com.sino.core.utils.Page","first":1,"hasNext":true,"hasPre":false,"nextPage":2,"order":"desc","orderBy":"id","orderByInfo":" id desc","orderBySetted":true,"pageNo":1,"pageSize":100,"prePage":1,"result":[{"PPP_ID":"B452B0BAA7004104E053D551A8C06C48","RPI_NAME":"何捷","SCO_NAME":"男","ECO_NAME":"本科","AOI_NAME":"爱建证券有限责任公司","PTI_NAME":"一般证券业务","CTI_NAME":"非证券经纪人","CER_NUM":"S0820108090403","PPP_GET_DATE":"2008-09-19","PPP_END_DATE":"2020-12-31","COUNTCER":"3","COUNTCX":null,"'

我们发现返回结果很像字典,此时我们可以使用resp.json()让结果显示更加有层次。

resp.json()
{'autoCount': True,
 'class': 'com.sino.core.utils.Page',
 'first': 1,
 'hasNext': True,
 'hasPre': False,
 'nextPage': 2,
 'order': 'desc',
 'orderBy': 'id',
 'orderByInfo': ' id desc',
 'orderBySetted': True,
 'pageNo': 1,
 'pageSize': 100,
 'prePage': 1,
 'result': [{'PPP_ID': 'B452B0BAA7004104E053D551A8C06C48',
   'RPI_NAME': '何捷',
   'SCO_NAME': '男',
   'ECO_NAME': '本科',
   'AOI_NAME': '爱建证券有限责任公司',
   'PTI_NAME': '一般证券业务',
   'CTI_NAME': '非证券经纪人',
   'CER_NUM': 'S0820108090403',
   'PPP_GET_DATE': '2008-09-19',
   'PPP_END_DATE': '2020-12-31',
   'COUNTCER': '3',
   'COUNTCX': None,
   'RNUM': 1},
  {'PPP_ID': 'B452B0BAA1474104E053D551A8C06C48',
   'RPI_NAME': '黎永红',
   'SCO_NAME': '女',
   'ECO_NAME': '大专',
   'AOI_NAME': '爱建证券有限责任公司',
   'PTI_NAME': '一般证券业务',
   'CTI_NAME': '非证券经纪人',
   'CER_NUM': 'S0820111070003',
   'PPP_GET_DATE': '2011-07-01',
   'PPP_END_DATE': '2020-12-31',
   'COUNTCER': '2',
   'COUNTCX': None,
   'RNUM': 2},
  {'PPP_ID': 'B452B0BA9EA04104E053D551A8C06C48',
   'RPI_NAME': '魏伟',
   'SCO_NAME': '男',
   'ECO_NAME': '本科',
   'AOI_NAME': '爱建证券有限责任公司',
   'PTI_NAME': '一般证券业务',
   'CTI_NAME': '非证券经纪人',
   'CER_NUM': 'S0820110120005',
   'PPP_GET_DATE': '2010-12-14',
   'PPP_END_DATE': '2020-12-31',
   'COUNTCER': '2',
   'COUNTCX': None,
   'RNUM': 3},
  ....
  ....
  {'PPP_ID': 'B452B0BB26304104E053D551A8C06C48',
   'RPI_NAME': '王洁芸',
   'SCO_NAME': '女',
   'ECO_NAME': '本科',
   'AOI_NAME': '爱建证券有限责任公司',
   'PTI_NAME': '一般证券业务',
   'CTI_NAME': '非证券经纪人',
   'CER_NUM': 'S0820108050358',
   'PPP_GET_DATE': '2008-05-15',
   'PPP_END_DATE': '2020-12-31',
   'COUNTCER': '1',
   'COUNTCX': None,
   'RNUM': 100}],
 'searchFileName': 'homepage',
 'sqlCKey': 'SIZE_FINISH_PUBLICITY',
 'sqlKey': 'PAGE_FINISH_PUBLICITY',
 'totalCount': 566,
 'totalPages': 6}

3. 解析数据

我们对resp.json()中的result字段感兴趣。result字段含有丰富的从业人员

aaiamqr.png!mobile

这里我们可以直接拿到

import pandas as pd

df = pd.DataFrame(resp.json()['result'])
df.head()
PPP_ID RPI_NAME SCO_NAME ECO_NAME AOI_NAME PTI_NAME CTI_NAME CER_NUM PPP_GET_DATE PPP_END_DATE COUNTCER COUNTCX RNUM 0 B452B0BAA7004104E053D551A8C06C48 何捷 男 本科 爱建证券有限责任公司 一般证券业务 非证券经纪人 S0820108090403 2008-09-19 2020-12-31 3 None 1 1 B452B0BAA1474104E053D551A8C06C48 黎永红 女 大专 爱建证券有限责任公司 一般证券业务 非证券经纪人 S0820111070003 2011-07-01 2020-12-31 2 None 2 2 B452B0BA9EA04104E053D551A8C06C48 魏伟 男 本科 爱建证券有限责任公司 一般证券业务 非证券经纪人 S0820110120005 2010-12-14 2020-12-31 2 None 3 3 B452B0BAAF754104E053D551A8C06C48 凌建刚 男 高中 爱建证券有限责任公司 一般证券业务 非证券经纪人 S0820100010136 2004-04-09 2020-12-31 1 None 4 4 B452B0BAAF7B4104E053D551A8C06C48 余琦文 女 大专 爱建证券有限责任公司 一般证券业务 非证券经纪人 S0820100010135 2004-05-10 2020-12-31 1 None 5

4. 存储数据

这里我偷懒了,直接使用了pandas的df.to_csv('文件路径', mode='a+')

mode采用a+追加方式,这样后续有新内容存入csv时,csv内已有的内容不会被擦除掉。

df.to_csv('安信员工信息.csv', mode='a+')

5. 整合

重复步骤2-4

import requests
import pandas as pd

#证券企业的id
company_id = '1999082'

#该证券企业的人员信息有55页
for page in range(1, 56):
#构造data参数
url = 'https://exam.sac.net.cn/pages/registration/train-line-register!list.action'
data = {'filter_EQS_AOI_ID': company_id,
'filter_EQS_PTI_ID': 0,
'page.searchFileName': 'homepage',
'page.sqlKey': 'PAGE_FINISH_PUBLICITY',
'page.sqlCKey': 'SIZE_FINISH_PUBLICITY',
'_search': 'false',
'page.pageSize': 100,
'page.pageNo': page,
'page.orderBy': 'id',
'page.order': 'desc'}

#post方法访问某页
resp = requests.post(url, data=data, verify=False)

#解析网页数据
df = pd.DataFrame(resp.json()['result'])

#存储数据
df.to_csv('安信员工信息.csv', mode='a+')

爬虫正常运行,没出什么幺蛾子

查看数据

查看我们的数据

import pandas as pd

df = pd.read_csv('安信员工信息.csv')
#df.dropna(inplace=True)
df.head()
Unnamed: 0 PPP_ID RPI_NAME SCO_NAME ECO_NAME AOI_NAME PTI_NAME CTI_NAME CER_NUM PPP_GET_DATE PPP_END_DATE COUNTCER COUNTCX RNUM 0 0.0 B452B0BAA7004104E053D551A8C06C48 何捷 男 本科 爱建证券有限责任公司 一般证券业务 非证券经纪人 S0820108090403 2008-09-19 2020-12-31 3 NaN 1 1 1.0 B452B0BAA1474104E053D551A8C06C48 黎永红 女 大专 爱建证券有限责任公司 一般证券业务 非证券经纪人 S0820111070003 2011-07-01 2020-12-31 2 NaN 2 2 2.0 B452B0BA9EA04104E053D551A8C06C48 魏伟 男 本科 爱建证券有限责任公司 一般证券业务 非证券经纪人 S0820110120005 2010-12-14 2020-12-31 2 NaN 3 3 3.0 B452B0BAAF754104E053D551A8C06C48 凌建刚 男 高中 爱建证券有限责任公司 一般证券业务 非证券经纪人 S0820100010136 2004-04-09 2020-12-31 1 NaN 4 4 4.0 B452B0BAAF7B4104E053D551A8C06C48 余琦文 女 大专 爱建证券有限责任公司 一般证券业务 非证券经纪人 S0820100010135 2004-05-10 2020-12-31 1 NaN 5

如果感兴趣,可以下载本教程的代码

链接:https://pan.baidu.com/s/1wPazvcNegYPXmCiSkPkamg  密码:lx0m

原创不易,请多转发点赞支持~

近期文章

Python网络爬虫与文本数据分析

bsite库 | 采集B站视频信息、评论数据

rpy2库 | 在jupyter中调用R语言代码

tidytext | 耳目一新的R-style文本分析库

reticulate包 | 在Rmarkdown中调用Python代码

plydata库 | 数据操作管道操作符>>

七夕礼物 | 全网最火的钉子绕线图制作教程

读完本文你就了解什么是文本分析

文本分析在经管领域中的应用概述

综述:文本分析在市场营销研究中的应用

plotnine: Python版的ggplot2作图库

小案例: Pandas的apply方法   

stylecloud:简洁易用的词云库  

用Python绘制近20年地方财政收入变迁史视频   

Wow~70G上市公司定期报告数据集

漂亮~pandas可以无缝衔接Bokeh

YelpDaset: 酒店管理类数据集10+G

分享 ”和“ 在看 ”是更好的支持!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK