Stata连享会 主页 || 视频 || 推文 || 知乎 || Bilibili 站
温馨提示: 定期 清理浏览器缓存,可以获得最佳浏览体验。
New!
lianxh
命令发布了:
随时搜索推文、Stata 资源。安装:
. ssc install lianxh
详情参见帮助文件 (有惊喜):
. help lianxh
连享会新命令:cnssc
,ihelp
,rdbalance
,gitee
,installpkg
⛳ Stata 系列推文:
作者:范思妤 (南京大学)
邮箱:fansiyu@smail.nju.edu.cn
目录
科创板试点的注册制改革,强调“以信息披露为核心”。为在发行上市审核坚持以信息披露为核心,把好上市企业入口质量关,上交所主要采用公开化问询式审核方式,即交易所提出问询的问题,发行人对这些问题进行回复和说明,中介机构对问询事项的核查过程和结论,以“一问一答”的方式及时向市场公开。
本文重点关注如何通过 Python 的 selenium
库爬取上述审核问询流程披露的原始文件,并在发行公司层面对问询与回复情况进行汇总统计。
在本文中,我们使用 Python 中的 selenium
库对网页进行爬取。selenium
通过创建模拟浏览器的方式进行爬取,可以完全模拟真实用户的动态操作。在配置好 Python 环境后,打开命令提示符,并键入如下命令安装 selenium
库:
pip install selenium
或者使用国内镜像源安装 selenium
库:
pip install selenium -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
接下来,我们需要安装浏览器驱动。此处我们主要讲解 Windows 系统安装 chrome 浏览器驱动的步骤和方法。其他系统及其他浏览器驱动的安装,请自行网络搜索相关教程。
首先,我们需要确定 chrome 浏览器版本。打开 chrome 浏览器,在新标签页输入 chrome://settings/help
进入设置界面,查看目前的版本信息。
在获取浏览器版本信息后,需下载对应版本的浏览器驱动。打开 chrome 浏览器 驱动下载地址,找到和目前版本最接近的驱动,Windows 系统用户需下载 win32 版本。
解压驱动文件包得到 chromedriver.exe
,保存到指定路径,并务必将当前路径添加到环境变量中(我的电脑
我们使用如下代码创建浏览器驱动对象。此外,我们可以根据爬虫目标网页调整浏览器选项,提供稳定运行环境。
from selenium import webdriver
from selenium.webdriver import ChromeOptions
CHROME_OPTIONS = webdriver.ChromeOptions()
prefs = {"profile.managed_default_content_settings.images":2} # 1代表显示图片,2代表不显示图片
CHROME_OPTIONS.add_experimental_option("prefs", prefs)
CHROME_OPTIONS.add_experimental_option("excludeSwitches",["enable-automation"])
CHROME_OPTIONS.add_experimental_option("useAutomationExtension", False)
CHROME_OPTIONS.add_argument('--disable-blink-features=AutomationControlled')
CHROME_DRIVER = r'D:/chromedriver/chromedriver.exe' # 此处为chromedriver.exe所在路径
# 声明浏览器
driver = webdriver.Chrome(executable_path=CHROME_DRIVER, options=CHROME_OPTIONS)
首先,我们需要浏览待爬取的页面结构,并检查网页确定网页类型。
上交所科创板股票审核页面如下。最上方一行分类列示已递交申请的发行人的状态,我们的样本仅爬取已经有注册结果的发行人(即已经走完整个科创板审核问询流程。
所有发行人按照时间由近及远的顺序列示在页面表格中。每行发行人全称对应一个超链接,点击即进入发行人审核问询的详情页面。因此,我们整体的爬虫思路如下:
如上所述,我们仅爬取已经有注册结果的发行人。因此,首先需要用 selenium
自动化模拟鼠标点击操作,以点击页面上方的“注册结果”,获取跳转后的页面上的信息。
# 导入所需要的包
from selenium.webdriver.common.by import By
import time
# 请求页面
url = "http://kcb.sse.com.cn/renewal/"
driver.get(url)
# 通过Xpath定位到“注册结果”,并点击,等待页面加载
driver.find_element(By.XPATH,'//*[@id="select5"]/a/span[2]').click()
time.sleep(3)
通过加载后的检查页面,我们发现 url 就包含在发行人全称的 href 属性中。我们进行如下步骤的操作以获取完整的发行人 url 列表:
selenium
提供了多种元素定位方式,如 xpath,id,name 等。在本文中,我们用 Xpath 定位元素。具体步骤如下图,得到对应元素的 Xpath 后,通过语法 @href
选取元素属性。
代码如下:
# Xpath定位元素
all_url_list = []
url_xpath = '//*[@id="dataList1_container"]/tbody/tr/td[2]/a/@href'
next_page = '//*[@id="dataList1_container_next"]/span'
# 获取发行人url列表
for i in range(1,28): # 最大页数是28
print("正在抓取第%s页的内容" %i)
html = driver.page_source
tree = etree.HTML(html)
url_list = tree.xpath(url_xpath)
all_url_list.extend(url_list)
time.sleep(1)
if i<=26 :
# 点击下一页
driver.find_element(By.XPATH,next_page).click()
time.sleep(2) # 等待页面加载
else:
pass # 最后一页没有“下一页”
driver.quit()
# 打印最后10个url,检查是否所有url爬取成功
for url in all_url_list[-10:]:
print(url)
在获取了全部发行人 url 列表之后,我们需要遍历 url 列表,获取特定发行人审核问询的详情页面。在这一页面,我们需要爬取的关键内容如下:
发行人基本信息:
审核问询披露文件:
代码如下:
#————爬取每个url对应的科创板发行上市公司页面————#
# 导入所需的包
import time
from lxml import etree
import pandas as pd
from selenium import webdriver
from selenium.webdriver.common.by import By
import requests
import os
from urllib.request import urlretrieve
# 在路径下创建文件夹
os.mkdir(r'./companies')
# 浏览器驱动配置及使用
CHROME_OPTIONS = webdriver.ChromeOptions()
prefs = {"profile.managed_default_content_settings.images":2} # 1代表显示图片,2代表不显示图片
CHROME_OPTIONS.add_experimental_option("prefs", prefs)
CHROME_DRIVER = r'D:/chromedriver/chromedriver.exe'
driver = webdriver.Chrome(executable_path=CHROME_DRIVER, options=CHROME_OPTIONS)
# 发行人基本信息的Xpath定位
fullname_xpath = '//*[@id="issuer_full"]'
shortname_xpath = '//*[@id="issuer_sec"]'
broker_xpath = '//*[@id="sponsor_org"]/a'
auditor_xpath = '//*[@id="accounts_org"]/a'
lawyer_xpath = '//*[@id="law_firm"]/a'
acceptdate_xpath = '//*[@id="step1F"]/div'
inquirydate_xpath = '//*[@id="step2F"]/div'
passdate_xpath = '//*[@id="step3F"]/div'
# 注册制审核问询披露文件的Xpath定位
SECLetter_xpath = '//*[@id="yjhf"]/tbody/tr/td[2]/a'
# 创建空列表以盛放后续爬虫信息
all_fullname = []
all_shortname = []
all_broker = []
all_auditor = []
all_lawyer = []
all_acceptdate = []
all_inquirydate = []
all_passdate = []
all_num_letter1 = []
all_num_letter2 = []
all_num_letter3 = []
for url_item in all_url_list:
url = 'http://kcb.sse.com.cn' + url_item
driver.get(url)
time.sleep(2)
html = driver.page_source
tree = etree.HTML(html)
# 获取发行人基本信息的文本节点
fullname_list = tree.xpath(fullname_xpath + '/text()')
all_fullname.append(fullname_list[0])
shortname_list = tree.xpath(shortname_xpath+ '/text()')
all_shortname.append(shortname_list[0])
broker_list = tree.xpath(broker_xpath+ '/text()')
content = ';'.join(broker_list) # 可能会有多个保荐机构,用分号链接,下同
all_broker.append(content)
auditor_list = tree.xpath(auditor_xpath+ '/text()')
content = ';'.join(auditor_list)
all_auditor.append(content)
lawyer_list = tree.xpath(lawyer_xpath+ '/text()')
content = ';'.join(lawyer_list)
all_lawyer.append(content)
acceptdate_list = tree.xpath(acceptdate_xpath+ '/text()')
all_acceptdate.append(acceptdate_list[0])
inquirydate_list = tree.xpath(inquirydate_xpath+ '/text()')
all_inquirydate.append(inquirydate_list[0])
passdate_list = tree.xpath(passdate_xpath+ '/text()')
all_passdate.append(passdate_list[0])
# 获取问询与回复信息的文本节点
SECLetter_list = tree.xpath(SECLetter_xpath + '/text()')
# 获取问询与回复的href属性,为后续下载对应文件pdf做准备
SECLetter_url = tree.xpath(SECLetter_xpath + '/@href')
# 为每一公司创建子文件夹,用以盛放分类后的文件pdf
os.mkdir('./companies/'+fullname_list[0])
os.mkdir('./companies/'+fullname_list[0] + '/问询函和回函/')
os.mkdir('./companies/'+fullname_list[0] + '/审计意见/')
os.mkdir('./companies/'+fullname_list[0] + '/法律意见/')
os.mkdir('./companies/'+fullname_list[0] + '/其他/')
# 注册制审核问询披露文件的计数算子
count_letter1 = 0
count_letter2 = 0
count_letter3 = 0
#获取pdf文件方法1,用requests.get:
for i in range(len(SECLetter_list)):
url = SECLetter_url[i]
r = requests.get('http:'+ url)
# 通过文件名称对文件进行分类,并计数
if ('发行人'in SECLetter_list[i]) or ('落实函' in SECLetter_list[i]) \
and ('会计' not in SECLetter_list[i]) and ('律师'not in SECLetter_list[i]) \
and ('法律' not in SECLetter_list[i]):
with open('./companies/'+fullname_list[0] + '/问询函和回函/'+SECLetter_list[i]+'.pdf', 'wb+') as f:
f.write(r.content)
count_letter1 += 1
elif '会计' in SECLetter_list[i]:
with open('./companies/'+fullname_list[0] + '/审计意见/'+SECLetter_list[i]+'.pdf', 'wb+') as f:
f.write(r.content)
count_letter2 += 1
elif ('律师'in SECLetter_list[i]) or ('法律' in SECLetter_list[i]):
with open('./companies/'+fullname_list[0] + '/法律意见/'+SECLetter_list[i]+'.pdf', 'wb+') as f:
f.write(r.content)
count_letter3 += 1
else :
with open('./companies/'+fullname_list[0] + '/其他/'+SECLetter_list[i]+'.pdf', 'wb+') as f:
f.write(r.content)
all_num_letter1.append(count_letter1)
all_num_letter2.append(count_letter2)
all_num_letter3.append(count_letter3)
'''
# 获取pdf文件方法2,用urlretrieve:
# 以下代码仅做方法思路展示,未对pdf进行进一步分类
for i in range(len(SECLetter_list)):
url = 'http:' + SECLetter_url[i]
urlretrieve(url,filename = './科创板/companies/'+fullname_list[0]+'/'+SECLetter_list[i]+'.pdf')
'''
driver.quit()
# 将爬虫信息储存到本地excel文件
file = r".\科创板注册制信息披露.xlsx"
final_data = [all_fullname,all_shortname,all_broker,all_auditor,all_lawyer,all_acceptdate, \
all_inquirydate,all_passdate,all_num_letter1,all_num_letter2,all_num_letter3]
df = pd.DataFrame(final_data).T
df.columns = ["公司全称", "公司简称", "保荐机构", "会计师事务所", "律师事务所","受理日期", \
"开始问询日期","上市委通过日期","问询与回函数量","审计意见数量","律师意见数量"]
df.to_excel(file, index = None)
最终,我们可以得到如下审核问询情况汇总及审核问询披露文件的原始 pdf:
注意:以上代码在计算“问询与回函数量”、“审计意见数量”、“律师意见数量”时仅简单地计数页面上所列示的对应文件的数量,但并不代表发行人实际被问询次数。在现实中,若公司在季度末或者年末更新财务报表,则需根据更新后的财务报表向交易所重新提交以上文件。举个例子:《发行人及保荐机构回复意见》和《发行人及保荐机构回复意见(2022年半年报财务数据更新版)》本质上属于同一份回函的两个版本,计算一次问询次数,而不是两次。此处请读者仔细甄别。
Note:产生如下推文列表的 Stata 命令为:
lianxh 爬虫, m
安装最新版lianxh
命令:
ssc install lianxh, replace
免费公开课
最新课程-直播课
专题 | 嘉宾 | 直播/回看视频 |
---|---|---|
⭐ 最新专题 | 文本分析、机器学习、效率专题、生存分析等 | |
研究设计 | 连玉君 | 我的特斯拉-实证研究设计,-幻灯片- |
面板模型 | 连玉君 | 动态面板模型,-幻灯片- |
面板模型 | 连玉君 | 直击面板数据模型 [免费公开课,2小时] |
⛳ 课程主页
⛳ 课程主页
关于我们
课程, 直播, 视频, 客服, 模型设定, 研究设计, stata, plus, 绘图, 编程, 面板, 论文重现, 可视化, RDD, DID, PSM, 合成控制法
等
连享会小程序:扫一扫,看推文,看视频……
扫码加入连享会微信群,提问交流更方便
✏ 连享会-常见问题解答:
✨ https://gitee.com/lianxh/Course/wikis
New!
lianxh
和songbl
命令发布了:
随时搜索连享会推文、Stata 资源,安装命令如下:
. ssc install lianxh
使用详情参见帮助文件 (有惊喜):
. help lianxh