赵嘉明的作业三

代码


  # -*- coding: utf-8 -*-
"""
Created on Tue May 10 01:42:20 2022

@author: pc
"""
#赵嘉明,关宇翔,徐蕾小组作业
import re
import pandas as pd
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
from selenium.webdriver.support.wait import WebDriverWait


browser = webdriver.Chrome()
browser.get('https://www.szse.cn/disclosure/listed/fixed/index.html')
element = browser.find_element(By.ID, 'input_code')         # ID定位到搜索框
element.send_keys('华茂股份' + Keys.RETURN)                   # 输入想要查找的企业
time.sleep(2)


def element_exist(driver,element):                         #判断企业年报数量是否存在下一页
    flag = True
    try:
        driver.find_element(By.PARTIAL_LINK_TEXT,element)
        return flag
    except:
        flag = False
        return flag

trs=[]

for r in range(5):                                              #这里的最大页数范围我不知道怎么确定,默认爬取五页
    time.sleep(2)                                                   #这里要加等待时间,不然定位不到下一页的元素

    element = browser.find_element(By.ID, 'disclosure-table')  # ID定位到年报表格
    innerHTML = element.get_attribute('innerHTML')          # 获取年报标签下的源代码

    f = open('innerHTML.html','w',encoding='utf-8')           # 将源代码写入本地文件
    f.write(innerHTML)
    f.close()

    f = open('innerHTML.html',encoding='utf-8')               # 读取年报源代码文件
    html = f.read()
    f.close()
    soup = BeautifulSoup(html,features='lxml')              #利用bs进行解析
    html_prettified = soup.prettify()                       #格式标准化代码
    p = re.compile('(.*?)', re.DOTALL)             #利用正则表达式 找到所需链接的tr标签
    tr = p.findall(html_prettified)
    trs.extend(tr)                                          #把每一次爬取到的tr标签添加到trs这个空列表中

    flag = element_exist(browser,'下一页')                   #通过写好的函数判断是否有下一页,如果有则循环爬取
    if flag:
        nextpage = browser.find_element(By.PARTIAL_LINK_TEXT,'下一页')  #通过部分文本定位到下一页
        nextpage.click()                                                #点击下一页
        wait = WebDriverWait(browser, 2)
    else:                                                   #如果没有下一页,终止爬取
        break


prefix = 'https://disc.szse.cn/download'                #为后面提取的链接设定好下载前缀网址
prefix_href = 'http://www.szse.cn'                      #为后面提取的链接设定好查看前缀网址
p2 = re.compile('(.*?)', re.DOTALL)         #在tr标签下进一步提取td标签下的内容
tds = [p2.findall(tr) for tr in trs[1:]]                #循环搜索提取trs里的所有项目

#注:此处因为前面翻页时,tds列表存在空列表,下面td[0]会报错,要把空列表过滤。
tds = list(filter(None,tds))

p_code = re.compile('(.*?)', re.DOTALL)       #在td标签下爬取企业代码,注:tds里的每一个项目都是一个列表
codes = [p_code.search(td[0]).group(1).strip() for td in tds]


p_shortname = p_code                                    #在td标签下爬取企业名字
short_names = [p_shortname.search(td[1]).group(1).strip() for td in tds]

p_link_ftitle = re.compile('(.*?)',
                           re.DOTALL)
link_ftitles = [p_link_ftitle.findall(td[2])[0] for td in tds] #在td标签下精确提取所需链接

p_pub_time = re.compile('(.*?)', re.DOTALL) #在td标签下爬取年报时间
p_times = [p_pub_time.search(td[3]).group(1) for td in tds]


df = pd.DataFrame({'证券代码': codes,
                   '简称': short_names,
                   '公告标题': [lf[2].strip() for lf in link_ftitles],
                   'attachpath': [prefix+lf[0].strip() for lf in link_ftitles],
                   'href': [prefix_href+lf[1].strip() for lf in link_ftitles],
                   '公告时间': [t.strip() for t in p_times]
    })                                                  #将数据导入至dataframe


df.to_csv('data.csv')                                   #将数据写入本地文件



结果

结果截图 结果截图 结果截图

解释

见代码注释