经过前三课的规划和准备,同学们熟悉了Python和数据库MySQL和分析网页工具-“开发者工具”,并建立了5个数据表用于存放上市公司利润表、资产负债表、现金流量表、财务比率表和MJ数字力分析表。
今天,我们要具体完成拆解上市公司财报数据网页,并写入数据库
1、解析出必要的数据块,
2、用一个新的模块批量吸取规则数据,
3、写入数据库
一、分析上市公司财报数据网页,解析必要数据块
从利润表开始
现在用google chrome浏览器,打开链接
http://stockdata.stock.hexun.com/2008/lr.aspx?stockid=002460&accountdate=2016.12.31
是某上市公司的2016年利润表年报,用快捷键ctrl+shift+I激活开发者工具.如图
现在,我们发现代码
是我们需要的
为什么需要这个代码段,而不是其他的?
原因是这个代码段是左边数据块最小代码量。
往上可以看到多个能覆盖左边数据块的代码。
往下再也找不到能细化覆盖左边数据块的代码了。
这就是要紧的、要注意的地方。
另外发现了一个爬虫类集,推荐同学们收藏仔细理解:
Python 爬虫的工具列表
http://python.jobbole.com/82633/
Python-第三方库requests详解
根据这些资源,我模仿写下下面命令,做第一次爬取操作。
>>> from bs4 import BeautifulSoup as bsoup ###导入爬虫函数库
>>> import json ###
>>> import requests ###导入通用网络库
>>> url = 'http://stockdata.stock.hexun.com/2008/lr.aspx?stockid=002460&accountdate=2016.12.31' #目标网址
>>> data = {'some': 'data'} ###格式
>>> headers = {'content-type': 'application/json',
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0'} ###定制头部内容
>>> r = requests.post(url, data=data, headers=headers)
>>> soup = bsoup(r.text,"html.parser")
>>> table_div = soup.findAll('div',id = 'zaiyaocontent') ###爬取指定代码包含的html
>>> print (table_div) ###查看分离出来的代码段是不是包含了我们想要的内容,如果没有,就说明最小代码量标志是错误的,需要多核对多调整。
这里同学们会发现上面的代码和前面讲的有点点不一样。为什么我加了下面的代码:
>>> data = {'some': 'data'}
>>> headers = {'content-type': 'application/json',
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0'} ###定制头部
因为我遇到一个坑,有些网站服务器会记录来访的浏览器信息。正常浏览器都会提交自己是什么版本的浏览器。你可以理解成地推时要进对方公司需要登记身份证信息的情况。这两句就是提交这个访问时自报家门的意思。当时没有提交浏览器版本,反馈的信息就是网页不存在。带上版本信息会得到贵宾待遇。:)
这里是Python反馈的结果:
经过刚才筛选的结果,里面可以看到利润表的所有数据项。以上是通用爬取网页数据的方法,这里要使用另一种爬取网络规则数据的方法
二、PyQuery
换用PyQuery的原因大家不难猜到。上图所列上市公司利润表数据,仔细观察可以用记事本逐行手工分割出现下面的规律
某种会计科目XXX,XXX,XXX.XX
.................................................
.................................................
补充两个函数库,用来读取规则数据和写入数据库
安装PyQuery: pip install pyquery
下面是分解和验证过程
>>> from pyquery import PyQuery as pq
>>> url = 'http://stockdata.stock.hexun.com/2008/lr.aspx?stockid=002460&accountdate=2016.12.31' #目标网址
>>> data = {'some': 'data'} ###格式
>>> headers = {'content-type': 'application/json',
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0'} ###定制头部内容
>>> r = pq(url, data=data, headers=headers)
>>> doc = r("div#zaiyaocontent table")###http://www.runoob.com/cssref/css-selectors.html CSS 选择器
>>> print (doc('table').text())
>>> print (doc('tr'))
验证结果集中在这张图片里展示
三、打造掘进飞轮-叶片
可以看出这些数据符合抓取要求。下面我们把它们装入数据库。
先细化逐项提取过程和装入数据库提交过程,最后我们就可以把它们组装成批量导入数据库的程序块。ok,我们开始打磨第一只飞轮叶片程序
程序如下:
#import pandas as pd
from datetime import datetime
import pymysql #数据库操作模块库
from pyquery import PyQuery as pq
connect = pymysql.Connect(
host='localhost',
port=3306,
user='Taylor007er',
passwd='007123',
db='hexun_mj', ###打开已经建好的hexun_mj数据库
charset='utf8')
#组合目标网址
stockid = '002460'
accountdate = '2016.12.31'
url = 'http://stockdata.stock.hexun.com/2008/lr.aspx?stockid=%s&accountdate=%s'%(stockid,accountdate) #利润表网址
#url = 'http://stockdata.stock.hexun.com/2008/zcfz.aspx?stockid=%s&accountdate=%s'%(stockid,accountdate) #资产负债表网址
#url = 'http://stockdata.stock.hexun.com/2008/xjll.aspx?stockid=%s&accountdate=%s'%(stockid,accountdate) #现金流量表网址
#url = 'http://stockdata.stock.hexun.com/2008/cwbl.aspx?stockid=%s&accountdate=%s'%(stockid,accountdate) #财务比率
data = {'some': 'data'} ###头部数据,固定格式
cookies = {'Cookie':' __jsluid=9b6511eb0809479912e4f096dfc528f0; vjuids=20165650e.1620f159997.0.26f3496d7aa07; vjlast=1520671497.1520671497.30; __utma=194262068.706268376.1520671497.1520671497.1520671497.1; __utmc=194262068; __utmz=194262068.1520671497.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmt=1; __utmb=194262068.1.10.1520671497; HexunTrack=SID=201803101644021464bf80816e9b346028c9d9b04557a4851&CITY=51&TOWN=0; ASP.NET_SessionId=0ic3eexu212ace5gqwjbamwb'}
headers = headers = {'Host':'stockdata.stock.hexun.com','Connection':'keep-alive','Cache-Control':'max-age=0','Upgrade-Insecure-Requests':'1','User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36','Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8','Accept-Encoding':'gzip, deflate','Accept-Language':'zh-CN,zh;q=0.9','If-Modified-Since':'Sat, 10 Mar 2018 08:43:10 GMT'}
r = pq(url=url,data=data,headers=headers,cookies=cookies) #读取网页
doc = r("div#zaiyaocontent table")#筛选出上市公司财务数据 ## #http://www.runoob.com/cssref/css-selectors.html CSS 选择器
data = doc('tr')
v_1=[]
v_2=[]
v_2.append(stockid) #第一个位置是stockid
for data in doc('tr'):
v_code = pq(data).find('td').eq(0).text()
v_vaule = pq(data).find('td').eq(1).text()
if v_vaule.count('.')>=2: #字符串里包含两个. 就是日期,不用改
v_2.append(v_vaule)
elif v_vaule.count('--')>=1: #字符串里包含符合--,即数字为0
v_2.append(0)
elif v_vaule.count(',')>=1: #字符串里包含有‘,’说明数字很大,需要除掉逗号,并转换为数字
v_2.append(float(v_vaule.replace(',',''))) #转换为数字
elif len(v_vaule) == 0:v_2.append(v_vaule) #字符串为空
else: v_2.append(float(v_vaule))
print(v_2) #验证结果
上面 [ ..... ] 内容就是我们需要保存的数据。这里用了列表,用 [ ] 表示。
下面,我们把结果写入数据库。
#我建立了下面这个字符串变量__lrb30,表示利润表有30个字段,与v_2的值一一对应。
__lrb30 = '%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s'
print(v_2)
sql = "insert into hexun_lrb values(%s)"%__lrb30
print (sql)
cursor = connect.cursor()
cursor.execute(sql,v_2)
connect.commit()
#可以用select 验证数据是否写入表格里
>>> cursor = connect.cursor()
>>> sql = "select * from hexun_lrb" ###读取city这样一张表。
>>> cursor.execute(sql)
>>> for row in cursor.fetchall(): ### for 循环,配合下面循环体里的打印语句,打印cursor.fetchall()数组 每一行 元组,元组的值赋值给row
print (row) ###将结果输出到屏幕上
cursor.close()
connect.close()
下面是验证结果截图
至此,我们完成了吸星大法获取上市公司财务数据之--打磨完成第一个螺旋桨的任务,可以把单个公司的利润表写入数据库。具体完成拆解上市公司财报数据网页,1、解析出必要的数据块,2、用一个新的模块批量吸取规则数据,3、写入数据库。完整的一套。
下次课里,我们将完成吸星大法获取上市公司财务数据之--学习怎样批量爬取所有上市公司财报数据到本地数据库里?
期待你能根据今天的课完成至少一条数据记录写入数据库,在留言区告诉我,你完成的情况,提出自己的想法和问题。下次课见!
领取专属 10元无门槛券
私享最新 技术干货