Spider_东方财富
一、基于Selenuim爬取白酒行业各上市公司财务报表以及指标
1、确定目标网页
进入东方财富网——行业中心
“http://quote.eastmoney.com/center/boardlist.html#industry_board”
鼠标移动至”沪深板块“,再移动至”概念板块”,最后选择“白酒”,并Click
页面跳转至”http://quote.eastmoney.com/center/boardlist.html#boards2-90.BK0896“
即可观察所有相关目标公司都在此网页上,则确定URL,即在此页面上进行操作。当然使用Selenuim的话则目标网页可确定为行业中心网页。
2、分析目标数据结构并设计爬取循环及存储方式
def get_data():
(1)遍历循环白酒行业数据中心页面,提取公司名字,并作为首层循环,以达到爬取每个公司的目的
(2)二层循环:点击公司名称,进入该公司股票中心界面,定位“财务指标”并Click
(3)三层循环:爬取”主要指标“、”资产负债表“、”利润表“、”现金流量表“(注意按年度爬取,爬取每张表之前需要点击一次当前表”按年度“)。将每张表的数据构造二维数组datalist
Note:
A. 各表结构有所区别,每个tr标签下,th标签存放的是表格标题,td存放的才是内容,爬取时需要注意判断。此处观察结构后可知,每个tr标签下如果存在th标签,那就不会出现td标签,则利用判断len(td_list),如果len()==0则设置find_elements_by_tag_name(‘th’),即可达到提取标题的目的
**B.**此处存在tr标签的属性display:none,即在页面上是不可见的,导致爬取时会出现空白数组。解决方法是在爬取tr标签时,使用is_displayed()判断,”False“则continue
def save_data(name, datalist, datalist_zcfzb, datalist_lrb, datalist_xjllb):
(1)新建文件并add表
(2)将datalist二维数据表循环写入
(3)用”name“参数命名并保存文件
3、Coding:
1、注意find_element_(返回符合条件的第一个节点)和find_elements_(返回符合条件的多个节点)
2、多层循环的缩进问题
3、Selenuim跳转新的页面,要在当前页面继续操作需要获取当前页面的页柄才可。
import time
import xlwt
from selenium import webdriver
def main():
url = "http://quote.eastmoney.com/center/boardlist.html#boards2-90.BK0896"
getdata(url)
def getdata(url):
browser = webdriver.Chrome()
browser.get(url)
browser.maximize_window()
for page in range(1,3):
if(page==2):
browser.find_element_by_xpath('//*[@id="main-table_paginate"]/span[1]/a[2]').click()#第二页
time.sleep(3)
i=1# 行数
element = browser.find_element_by_id("table_wrapper-table")
trlist = element.find_elements_by_tag_name("tr") # 获得行
string1 = '//*[@id="table_wrapper-table"]/tbody/tr['
string2 = ']/td[3]/a'
for tr in trlist[i:]:
tdlist = tr.find_elements_by_tag_name("td") # 获得列
name = tdlist[2].text
string = string1 + str(i)+ string2
browser.find_element_by_xpath(string).click()
current_window = browser.window_handles
browser.switch_to_window(current_window[1])#获取当前页面页柄
browser.find_element_by_xpath('//*[@id="zjl_box"]/div[1]/ul/li[2]/h3/a').click() # 到达每个公司财务报表
time.sleep(2)
current_window = browser.window_handles
browser.switch_to_window(current_window[2])
browser.find_element_by_xpath('//*[@id="zyzbTab"]/li[2]').click()#主要指标按年度
time.sleep(2)
table = browser.find_element_by_class_name("needScroll")#主要指标
datalist = []
trlist = table.find_elements_by_tag_name("tr")
for item in trlist:
tdlist = item.find_elements_by_tag_name("td")
if len(tdlist) == 0:
tdlist = item.find_elements_by_tag_name("th")
cell = []
for it in tdlist:
cell.append(it.text)
datalist.append(cell)
browser.find_element_by_xpath('/html/body/div[1]/div[2]/div[6]/div[2]/div[1]/ul/li[2]').click()#资产负债表按年度
time.sleep(1)
table_zcfzb=browser.find_element_by_id('report_zcfzb_table')#资产负债表
datalist_zcfzb=[]
trlist_zcfzb=table_zcfzb.find_elements_by_tag_name("tr")
for item in trlist_zcfzb:
if(item.is_displayed()==False):#跳过隐藏标签
continue
tdlist_zcfzb=item.find_elements_by_tag_name("td")
if len(tdlist_zcfzb) == 0:
tdlist_zcfzb = item.find_elements_by_tag_name("th")
cell_zcfzb = []
for it in tdlist_zcfzb:
if(it.text=="审计意见(境内)"):#跳过审计意见
break
cell_zcfzb.append(it.text)
datalist_zcfzb.append(cell_zcfzb)
#for item in datalist_zcfzb:
# print(item)
browser.find_element_by_xpath('/html/body/div[1]/div[2]/div[7]/div[2]/div[1]/ul/li[2]').click()#利润表按年度
time.sleep(1)
table_lrb=browser.find_element_by_xpath("//*[@id='report_lrb_table']")#利润表
datalist_lrb=[]
trlist_lrb=table_lrb.find_elements_by_tag_name("tr")
for item in trlist_lrb:
if(item.is_displayed()==False):#跳过隐藏标签
continue
tdlist_lrb=item.find_elements_by_tag_name("td")
if len(tdlist_lrb) == 0:
tdlist_lrb = item.find_elements_by_tag_name("th")
cell_lrb = []
for it in tdlist_lrb:
if(it.text=="审计意见(境内)"):#跳过审计意见
break
cell_lrb.append(it.text)
datalist_lrb.append(cell_lrb)
browser.find_element_by_xpath('/html/body/div[1]/div[2]/div[8]/div[2]/div[1]/ul/li[2]').click()#现金流量表按年度
time.sleep(1)
table_xjllb=browser.find_element_by_xpath("//*[@id='report_xjllb_table']")#现金流量表
datalist_xjllb=[]
trlist_xjllb=table_xjllb.find_elements_by_tag_name("tr")
for item in trlist_xjllb:
if(item.is_displayed()==False):#跳过隐藏标签
continue
tdlist_xjllb=item.find_elements_by_tag_name("td")
if len(tdlist_xjllb) == 0:
tdlist_xjllb = item.find_elements_by_tag_name("th")
cell_xjllb = []
for it in tdlist_xjllb:
if(it.text=="审计意见(境内)"):#跳过审计意见
break
cell_xjllb.append(it.text)
datalist_xjllb.append(cell_xjllb)
#for item in datalist_zcfzb:
# print(item)
saveData(name, datalist,datalist_zcfzb,datalist_lrb,datalist_xjllb)
browser.close()
browser.switch_to_window(current_window[1])
browser.close()
browser.switch_to_window((current_window[0]))
i = i+1
browser.close()
def saveData(name, datalist, datalist_zcfzb, datalist_lrb, datalist_xjllb):
#file_str = './liquor_data/'+name+'_指标'+'.xls'
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('主要指标')
worksheet_zcfzb = workbook.add_sheet('资产负债表')
worksheet_lrb = workbook.add_sheet('利润表')
worksheet_xjllb = workbook.add_sheet('现金流量表')
n_row = len(datalist)
n_col = len(datalist[0])
for l in range(n_row):
for m in range(n_col):
worksheet.write(l , m, datalist[l][m])
n_row_1 = len(datalist_zcfzb)
n_col_1 = len(datalist_zcfzb[0])
for l in range(n_row_1-1):
for m in range(n_col_1):
worksheet_zcfzb.write(l , m, datalist_zcfzb[l][m])
n_row_2 = len(datalist_lrb)
for l in range(n_row_2-1):
for m in range(len(datalist_lrb[0])):
worksheet_lrb.write(l , m, datalist_lrb[l][m])
n_row_3 = len(datalist_xjllb)
n_col_3 = len(datalist_xjllb[0])
for l in range(n_row_3-1):
for m in range(n_col_3):
worksheet_xjllb.write(l , m, datalist_xjllb[l][m])
#workbook.save(file_str)
workbook.save(name+"财报"+".xls")
if __name__ == "__main__":
main()