目录
- 序言
- 函数模块介绍
- 创建模拟浏览器对象
- 只需要执行一次的部分
- 需要批量执行的重复操作部分(信息录入excel)
- 换页操作
- 主函数
- 本地文件结构
- 全部代码
- 结果预览
如果直接需要结果的,可以直接见文末,获取资源。
序言
新三板年报链接:https://www.neeq.com.cn/disclosure/announcement.html
需要提前下载好三个库,都可以用pip install轻松下载,稍微麻烦点儿的是需要去下载个对应版本的chromedriver.exe驱动,放到python或者Anaconda的文件夹目录下,然后添加环境变量(这部分报错了自行百度即可,操作起来不麻烦的)
注意time.sleep()是必要的,一是为了避免频繁操作被浏览器提醒,二是在网络不好的情况下让网页加载完全,否则都会导致报错
一定不要图快,目前我是2s左右完成一次。建议在网络环境较好的情况下运行
这之中还会遇到诸多问题,在代码的注释里也都写到了,其他需求可以做参考。
函数模块介绍
创建模拟浏览器对象
# 返回虚拟浏览器对象
def openUrl(url):driver = webdriver.Chrome()driver.get(url)time.sleep(2)return driver
只需要执行一次的部分
xpath如何获取百度一下即可
# 只运行一次,避免重复操作影响效率
def onceClick(driver):driver.find_element_by_xpath('//*[@id="root"]/div[4]/div/div/div[1]/div[1]/div/div[4]/div/div[2]/span[5]').click() time.sleep(2)
需要批量执行的重复操作部分(信息录入excel)
# 每一页的XPATH都是一样的,只需处理好一页即可
def judge(driver,df): global firmNofor i in range(1,21):element=driver.find_element_by_xpath(f'//*[@id="table"]/table/tbody/tr[{i}]/td[3]/a')text=element.textif '年度报告' in text and '年度报告摘要' not in text:firmNo=firmNo+1# 根据图片名称判断是创新层还是基础层try:stageelement = driver.find_element_by_xpath(f'//*[@id="table"]/table/tbody/tr[{i}]/td[1]/img')srcname=stageelement.get_attribute('src') if 'jj' in srcname:df['stage'][firmNo]='基础层'elif 'cy' in srcname:df['stage'][firmNo]='创新层'except:print('跳过层次认定')continue# 公司代码codeelement = driver.find_element_by_xpath(f'//*[@id="table"]/table/tbody/tr[{i}]/td[1]/a')code=codeelement.textdf['code'][firmNo]=code# 公司简称firmelement = driver.find_element_by_xpath(f'//*[@id="table"]/table/tbody/tr[{i}]/td[2]')firm=firmelement.textdf['firm'][firmNo]=firm# 报告年份index=text.index(':')year=text[index+1:index+5]df['year'][firmNo]=year# 年报链接urlelement = driver.find_element_by_xpath(f'//*[@id="table"]/table/tbody/tr[{i}]/td[4]/a')url=urlelement.get_attribute('href') df['url'][firmNo]=url# 发布日期dateelement = driver.find_element_by_xpath(f'//*[@id="table"]/table/tbody/tr[{i}]/td[5]')date=dateelement.textdf['date'][firmNo]=date df.to_csv('url.csv')
换页操作
由于年报链接在不同的页,需要模拟浏览器点击进行换页操作
# 换页
def turn_to_page(driver,page): if page==2:driver.find_element_by_xpath('//*[@id="root"]/div[4]/div/div/div[1]/div[3]/div/a[1]').click()elif page>=3 and page<=5:driver.find_element_by_xpath(f'//*[@id="root"]/div[4]/div/div/div[1]/div[3]/div/a[{page}]').click()if page>6:driver.find_element_by_xpath('//*[@id="root"]/div[4]/div/div/div[1]/div[3]/div/a[6]').click()print(f'已跳转至{page}页')
主函数
#主函数
if __name__ =='__main__':driver=openUrl('https://www.neeq.com.cn/disclosure/announcement.html')onceClick(driver)df=pd.DataFrame(columns=['stage','code','firm','year','url','date'],index=range(1,20000))for i in range(2,4000):judge(driver,df)turn_to_page(driver,i)time.sleep(2.5)driver.close()
本地文件结构
只需要将excel文件和代码文件放一起即可,或者用绝对路径也可
全部代码
from selenium import webdriver
import time
import pandas as pdfirmNo=0# 返回虚拟浏览器对象
def openUrl(url):driver = webdriver.Chrome()driver.get(url)time.sleep(2)return driver# 只运行一次,避免重复操作影响效率
def onceClick(driver):driver.find_element_by_xpath('//*[@id="root"]/div[4]/div/div/div[1]/div[1]/div/div[4]/div/div[2]/span[5]').click() time.sleep(2)# 每一页的XPATH都是一样的,只需处理好一页即可
def judge(driver,df): global firmNofor i in range(1,21):element=driver.find_element_by_xpath(f'//*[@id="table"]/table/tbody/tr[{i}]/td[3]/a')text=element.textif '年度报告' in text and '年度报告摘要' not in text:firmNo=firmNo+1# 根据图片名称判断是创新层还是基础层try:stageelement = driver.find_element_by_xpath(f'//*[@id="table"]/table/tbody/tr[{i}]/td[1]/img')srcname=stageelement.get_attribute('src') if 'jj' in srcname:df['stage'][firmNo]='基础层'elif 'cy' in srcname:df['stage'][firmNo]='创新层'except:print('跳过层次认定')continue# 公司代码codeelement = driver.find_element_by_xpath(f'//*[@id="table"]/table/tbody/tr[{i}]/td[1]/a')code=codeelement.textdf['code'][firmNo]=code# 公司简称firmelement = driver.find_element_by_xpath(f'//*[@id="table"]/table/tbody/tr[{i}]/td[2]')firm=firmelement.textdf['firm'][firmNo]=firm# 报告年份index=text.index(':')year=text[index+1:index+5]df['year'][firmNo]=year# 年报链接urlelement = driver.find_element_by_xpath(f'//*[@id="table"]/table/tbody/tr[{i}]/td[4]/a')url=urlelement.get_attribute('href') df['url'][firmNo]=url# 发布日期dateelement = driver.find_element_by_xpath(f'//*[@id="table"]/table/tbody/tr[{i}]/td[5]')date=dateelement.textdf['date'][firmNo]=date df.to_csv('url.csv')# 换页
def turn_to_page(driver,page): if page==2:driver.find_element_by_xpath('//*[@id="root"]/div[4]/div/div/div[1]/div[3]/div/a[1]').click()elif page>=3 and page<=5:driver.find_element_by_xpath(f'//*[@id="root"]/div[4]/div/div/div[1]/div[3]/div/a[{page}]').click()if page>6:driver.find_element_by_xpath('//*[@id="root"]/div[4]/div/div/div[1]/div[3]/div/a[6]').click()print(f'已跳转至{page}页')#主函数
if __name__ =='__main__':driver=openUrl('https://www.neeq.com.cn/disclosure/announcement.html')onceClick(driver)df=pd.DataFrame(columns=['stage','code','firm','year','url','date'],index=range(1,20000))for i in range(2,4000):judge(driver,df)turn_to_page(driver,i)time.sleep(2.5)driver.close()
结果预览
我获取的是2018-2022五年的所有年报的链接,文件放在下方链接,有需求自取,就无需在运行上述代码了。
https://download.csdn.net/download/weixin_43956523/88870592