转自同学的博客

引言:

网页爬虫分为静态网页爬虫和动态网页爬虫,前者是指索要获取的网页内容不需要经过js运算或者人工交互,

后者是指获取的内容必须要经过js运算或者人工交互。这里的js运算可能是ajax,人工交互不需要解释了。

静态爬虫现在已经很成熟了,借助于python中的urllib和beautifulsoup可以很容易实现,爬到的内容通

过python的字符串处理写入数据库,甚至可以通过web形式展现。动态爬虫有两种工具,一种是selenium,现

在是selenium2(selenium+webdriver),另一种是headless的phantomjs(对caperjs的封装),前者主要是

通过控制浏览器实现,尤其是那种带video tag的场合,例如国内的一些CP站点例如youku,后者则是不需要

展现内容的场合,或者可以理解为不带video tag的场合。据说后者的速度要比前者快,因为它不需要浏览器

展现,可以闷头去做。但是我只接触了了selenium这个工具……..

动态爬虫相对于静态爬虫,速度是要慢很多的。一般来说,用静态爬虫方法爬不到的数据,我们才采用动态爬虫工具爬取。 爬取的方法简单粗暴,和平常操作浏览器很是一个道理。

工具简介:

Selenium:是ThoughtWorks开发的一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等,在python里面有第三方库,可直接安装使用。详细介绍见百度百科:https://baike.baidu.com/item/Selenium/18266?fr=aladdin

chrome:就是谷歌浏览器,一款功能强大且齐全的浏览器。

工具准备以及环境搭建:

    python:首选Anacondaselenium:pip install selenium

关键就是用selenium驱动chrome: 首先在http://www.chromeliulanqi.com/下载32位版本的谷歌浏览器(注意是32位。64位貌似驱动不了)。然后下载驱动插件 链接:https://pan.baidu.com/s/1jIIjlwq 密码:xnl1

下载解压后,将chromedriver.exe 发到Python的安装目录,例如 D:\python 。 然后再将Python的安装目录添加到系统环境变量的Path下面

用下面的python代码简单测试一下:

from selenium import webdriver
browser = webdriver.Chrome()
browser.get('http://www.baidu.com/')

如果火狐浏览器自启并访问百度,则准备工作完成。

seleium的方法:

找了一篇相对详细具体的博客介绍http://blog.csdn.net/xfyangle/article/details/66478675,待会对目标网页分析的时候对具体方法说明一下。

开始爬取:

以下是巨潮资讯网的页面:

在个人财务数据那一栏,输入详细的公司代码,选择类别和年份,点击下载,浏览器就会下载并保存到本地了。我们用selenium驱动谷歌浏览器的话,其实也是一样的操作。

from selenium import webdriver #导入类库
driver = webdriver.Chrome()  #实例化浏览器对象

输入公司代码:


首先把鼠标点进代码文本框,右击审查元素,会看到这个文本框的网页源代码

选择用id进行定位,并向文本框中输入公司代码:

driver.find_element_by_id('index_cw_input_obj').send_keys("公司代码")

在这个网站下载了一份包含所有公司代码的csv文件,将公司代码提取出来,保存在数组中,用for循环不断send就可以了:

import csv
with open("20171226091635.csv","r") as csvfile:reader = csv.reader(csvfile)for line in reader:ID.append(line[0][1:])ID=ID[2:]     #ID就是包含所有公司代码的数组

提交了代码之后,会出现下拉选择条

把鼠标移到下面,选择审查:

driver.find_element_by_name("公司代码").click() #通过name,也就是刚才在文本框中输入的公司代码,来定位,然后点击

选择类别:

把鼠标移到类别框,审查元素

对于这种下拉菜单,有相应的方法选择其中的值,

from selenium.webdriver.support.ui import Select
select = Select(driver.find_element_by_css_selector('#index_select_type_obj'))
#通过css选择器,根据id定位到下拉菜单
select.select_by_index(j) #,选择相应的项,若j=0,则选择利润表,若j=1,则选择资产表,然后用for循环遍历3种表。

选择年份(本次只需要选择左边的年份,右边的默认当前年份):

同上:审查元素之后,根据id定位

select2 = Select(driver.find_element_by_id('cw_start_select_obj')) #通过id定位到年份
select2.select_by_index(j) #默认选择最老的年份,j=0

下载:

把鼠标移到下载按钮,点审查元素:

对于这个元素的定位,很奇怪,用id,name,xpath都不行,只能用css selector。对于css选择器以及xpath,我们不好直接知道他们具体的值,我们采用:对当前网页源代码这一行(如上图),右击,选择copy,然后选择copy selector 或者copy xpath,然后将复制的值,填到相应的方法的括号参数里面,即可定位。

driver.find_element_by_css_selector('#con-f-2 > div > div.down_button_row > button').click() #用css selector定位,然后用.click()方法点击改按钮,即可下载在你启动的浏览器中

这就是大概的一个流程,除了上述所说的过程之外。在两步操作之间,要设定一定的时间间隔,让浏览器反应一下,若浏览器没有加载出来,就会出现找不到元素的错误。以及在大量下载数据的过程中,每次下载一定数量的文件之后,网站会要求输入验证码才能下载(但是每次都输不对,过段时间又可以下载)。这就需要巧妙的用sleep函数设置休息间隔了。

代码实现:

from selenium import webdriver
from selenium.webdriver.support.ui import Select
import time
import csv
count=1 #下载计数
relax=1  #休息计数
ID=[]  #公司代码
NAME=[]  #公司名称
with open("20171226091635.csv","r") as csvfile:reader = csv.reader(csvfile)for line in reader:ID.append(line[0][1:])NAME.append(line[1])ID=ID[2:]NAME = NAME[2:]
driver = webdriver.Chrome()
driver.get("http://www.cninfo.com.cn/cninfo-new/index#")  #打开页面
time.sleep(5)   #等待5s
for i in ID:  #遍历所有的公司代码while (relax % 60) == 0:  #下载60个公司的报表,也就是点击下载180次,休息300stime.sleep(300)relax = relax + 1while(relax%40)==0:    #下载40个公司的报表,也就是点击下载130次,休息120s  time.sleep(120)relax=relax+1while(relax%20)==0:   #下载20个公司的报表,也就是点击下载60次,休息60stime.sleep(60)relax=relax+1driver.find_element_by_id('index_cw_input_obj').send_keys(i)   #向文本框提交公司代码driver.find_element_by_name(i).click() #选择相应的代码,点击print("正在下载第" + str(count) + "个:  代码: " + ID[count - 1] + "名称:  " + NAME[count - 1]+".....")   #可视化下载的过程for j in range(0,3):     #每个公司又3个表select1 = Select(driver.find_element_by_css_selector('#index_select_type_obj'))select1.select_by_index(j)   #选择相应的表select2 = Select(driver.find_element_by_id('cw_start_select_obj'))select2.select_by_index(0) #选择最久的年份driver.find_element_by_css_selector('#con-f-2 > div > div.down_button_row > button').click()    #点击下载time.sleep(3)   #等待3sprint("下载成功")    driver.find_element_by_id('index_cw_input_obj').clear() #将代码框中的代码清除count=count+1  #加一relax=relax+1   #加一time.sleep(2)   #下载完一个休息2s
print("下载完成")

本地处理:

下载的zip文件是一个一个散的,很无序,而且都没有解压。如图:

首先位每个公司创建目录,名称为公司代码_公司名称。然后在每个公司目录下面创建3个目录,以此为lrb,fzb,llb。

import os  #里面有创建文件夹的方法
import csv
count=0  #计数
ID=[]  #公司代码
NAME=[] #公司名称
with open("20171226091635.csv","r") as csvfile:reader = csv.reader(csvfile)for line in reader:ID.append(line[0][1:])NAME.append(line[1])ID=ID[2:]   NAME = NAME[2:]
os.mkdir("A股报表大全") #创建子目录
for x in ID:filename=x+'_'+NAME[count]  #将公司代码以及名称拼接起来if '*' in filename:filename=filename.replace("*","")  #把公司名称里面的*去掉,不然创建文件时会提示非法字符os.mkdir("A股报表大全/" + filename)    # (‘/’代表改目录的下一个目录)在A股报表大全目录下创建以公司代码_公司名称为名字的目录os.mkdir("A股报表大全/"+ filename  + "/" + "lrb")  #在公司目录下分别创建3个子目录os.mkdir("A股报表大全/" + filename + "/" + "fzb")os.mkdir("A股报表大全/" + filename + "/" + "llb")count=count+1

接下来就是把zip解压,然后放到对应的文档里面

import zipfile  #解压缩zip的库
import os
import csv
file_list = os.listdir(r'A股表压缩包大全.')
ID=[] #以 公司代码,公司名的形式循环存放
name="" #公司名称
table_tag="" #标记zip是什么类型的报表
file_dir=""
with open("20171226091635.csv","r") as csvfile:reader = csv.reader(csvfile)for line in reader:ID.append(line[0][1:])ID.append(line[1])
ID=ID[2:]
for file_name in file_list: #遍历压缩包目录if os.path.splitext(file_name)[1] == '.zip':print(file_name)count = 0id=file_name[7:13]  #在zip压缩包的文件名中取出公司代码table_tag=file_name[3:6]  #在zip压缩包的文件名中取出公司名称for i in ID:if i==id:name=ID[count+1]breakcount=count+1file_dir=str(id)+'_'+str(name) #为zip压缩包找到他对应的目录名if '*' in file_dir:file_dir=file_dir.replace("*","") #去掉*if table_tag=="lrb":  #如果是lrb表filedir="A股报表大全/"+file_dir + "/" + "lrb"file_zip = zipfile.ZipFile("A股表压缩包大全/"+ file_name)  #解压压缩包for file in file_zip.namelist(): #遍历压缩包里的文件file_zip.extract(file, filedir) #将file移动到filedir里面file_zip.close()  #关闭zip文件if table_tag=="fzb":filedir = "A股报表大全/" + file_dir + "/" + "fzb"file_zip = zipfile.ZipFile("A股表压缩包大全/"+ file_name)for file in file_zip.namelist():file_zip.extract(file, filedir)file_zip.close()if table_tag=="llb":filedir = "A股报表大全/" + file_dir + "/" + "llb"file_zip = zipfile.ZipFile("A股表压缩包大全/"+ file_name)for file in file_zip.namelist():file_zip.extract(file, filedir)file_zip.close()

自此, 完整的A股财务报表大全就有序的整理好了,可下载看看百度云链接

总结:由于每一次爬取次数的限制,以及驱动谷歌浏览器所出现的有时响应缓慢的问题,再加上一些未知错误(莫名的程序就停下来了)。本次爬取花了大概4天的时间将3455家公司,10365个zip文件爬下来,可以说要非常的有耐心了。代码不是关键,耐心才是重点。

以上若有不详细之处,可自行百度,或者同我交流。

基于python+selenium+Chrome自动化爬取巨潮资讯网A股财务报表相关推荐

  1. python 爬虫 requests+BeautifulSoup 爬取巨潮资讯公司概况代码实例

    第一次写一个算是比较完整的爬虫,自我感觉极差啊,代码low,效率差,也没有保存到本地文件或者数据库,强行使用了一波多线程导致数据顺序发生了变化... 贴在这里,引以为戒吧. # -*- coding: ...

  2. 批量爬取巨潮资讯网中“贵州茅台”相关公告的PDF文件。

    1 需求 批量爬取巨潮资讯网中"贵州茅台"相关公告的PDF文件. 2 代码实现 import reimport requests from selenium import webd ...

  3. python3爬取巨潮资讯网的年报数据

    python3爬取巨潮资讯网的年报数据 前期准备: 需要用到的库: 完整代码: 前期准备: 巨潮资讯网有反爬虫机制,所以先打开巨潮资讯网的年报板块,看看有什么解决办法. 巨潮咨询年报板块 可以通过这样 ...

  4. 巧用selenium爬取巨潮资讯公司数据

    巧用selenium爬取巨潮资讯公司数据 立项背景:在做深度学习的过程中利用python进行建模,需要数据来训练模型. 项目目标:通过运用python的selenium模块,爬取巨潮资讯网站关于公司的 ...

  5. selenium爬取巨潮资讯指定领域下所有上市公司的数据并存储到csv文件

    selenium爬取巨潮资讯指定领域下所有上市公司的数据并存储到csv文件 from selenium.webdriver import Chrome #引入selenium中的Chrome from ...

  6. python3爬取巨潮资讯网站年报数据

    python3爬取巨潮资讯网站年报数据 2018年年底巨潮资讯http://www.cninfo.com.cn改版了,之前实习生从网上找的脚本不能用了,因此重新修改了下爬取脚本.最初脚本的原链接忘了, ...

  7. python3爬取数据_python3爬取巨潮资讯网站年报数据

    python3爬取巨潮资讯网站年报数据 2018年年底巨潮资讯http://www.cninfo.com.cn改版了,之前实习生从网上找的脚本不能用了,因此重新修改了下爬取脚本.最初脚本的原链接忘了, ...

  8. 基于python的汽车信息爬取与可视化分析系统

    温馨提示:文末有 CSDN 平台官方提供的学长 Wechat / QQ 名片 :) 1. 项目简介 本项目利用网络爬虫技术从某汽车门户网站采集汽车数据,并利用 Flask + Echarts 前后端框 ...

  9. python + selenium +pyquery 爬虫 爬取 1688详情图片 阿里巴巴详情图片 与标题 下载图片并进行压缩

    python + selenium +pyquery 爬虫  爬取 1688详情图片 阿里巴巴详情图片 与标题 下载图片并进行压缩 用到的库和源码下载地址 需要用到chromedriver  包含wi ...

最新文章

  1. python逗号运算符_x,= ... - 这个尾随逗号是逗号运算符吗?
  2. 左击鼠标出现右击选项是怎么回事_跟着诗妍姐姐学电脑——鼠标
  3. mysql 死锁监视器_并发基础知识:死锁和对象监视器
  4. 那些大学简称背后的“爱恨情仇”:东西南北中,就剩北大没人抢了
  5. 轻量小巧的Knife4j v2.0.8源码
  6. 天天有毒_鸡汤文案类小程序源码
  7. Qt Installer Framework翻译(5-2)
  8. java内存与系统内存,Java获得jvm占用的内存和系统的可用内存信息详解
  9. sql程序实现事物锁表和解锁_怎样用SQL给SQL2880特定表加锁解锁
  10. Java8中list转map方法总结
  11. FineReport中统计列中不同数据的个数
  12. 超简单的动图制作、利用ps制作简单的动图、把动图导入我们的博客中;
  13. 敏捷-《如何准备ACP考试》知识图谱
  14. 河北大学计算机学院赵润,影视编导
  15. 【转】MEGA构建系统进化树的步骤(以MEGA7为例)
  16. linux日志查看技巧
  17. 【Redis集群专题】「集群技术三部曲」介绍一下常用的Redis集群机制方案的原理和指南(入门篇)
  18. 前瞻: 下一代网络 量子互联网
  19. 本地python环境快速迁移到另外一台电脑
  20. [Windows驱动]INF文件

热门文章

  1. vux组件的cell组件上下箭头图标显示问题,cell必须放在groud内才会显示
  2. 基于STM32的OLED显示
  3. R语言EG(Engle-Granger)两步法协整检验、RESET、格兰杰因果检验、VAR模型分析CPI和PPI时间序列关系...
  4. group by的用法
  5. 体育计算机培训心得体会,关于体育培训学习心得体会5篇
  6. 中控 X638考勤机编程(delphi)
  7. java图书分析echarts_【Echarts大数据分析】终于统计出水笔们了!都颤抖把!
  8. 中国大陆肯德基餐厅全面停用塑料吸管;可口可乐与时尚包袋品牌Kipling推出联名系列 | 美通企业日报...
  9. php格式转换成docx,如何在PHP中修改.doc或.docx文件
  10. Laravel 5文档阅读摘要