数据观察
沪、深证券交易所自1990年成立以来,已伴随中国经济发展将近30年了。在这将近30年里,沪、深股市起起落落、跌跌撞撞顽强走出了一条支撑中国企业、中国经济发展的股市成长道路。然而最近随着外部经济环境不断趋紧,国内经济也存在下行压力,沪深股市已经持续低迷相当长一段时间。为进一步了解沪深股市目前现状,这里使用python来爬取同花顺网上所有沪深上市公司基本信息以及当前市值信息,探讨沪深股市总体情况以及企业经营现状。
一、需求分析
(1)获得上证、深证所有上市公司名称与证券代码,包括上证A股、深证A股、创业板和中小板所有上市公司;
(2)获取各上市公司基本信息,包括所属地域、主营业务、上市日期、每股净资产、每股收益、净利润、净利润增长率、营业收入、每股现金流、每股公积金、每股未分配利润、总股本、流通股等信息;
(3)获取各上市公司当前市值情况,包括当前总市值、市净率、流通市值、市盈率等信息。
二、网页分析
根据数据获取需求,爬取网页主要有以下三块:
1、个股行情
image
2、公司简介
image
3、个股当前信息
image
三、爬虫思路
为便于数据处理方便,在本地搭建一个MYSQL数据库,将抓取的数据直接存入数据库中。程序抓数主要过程为:
(1) 通过个股行情页面,获得所有上市公司名称、股票代码、上市板块以及详细信息链接,然后将这些信息存入数据表一;在仔细分析各版块网页时,可发现网址未发生变化,而内容发生变化,这属于异步请求。打开F12查看Network中XHR发现会每次点击都会多出来一行,而多出一行的网址就是异步提取得数据,因此可以通过爬取该网页获得异步请求数据;
image
image
(2)在详细信息链接中,抓数分为两块,一是公司简介,这属于静态网页,为提高抓数效率,直接可使用requests模块抓取;
(3)二是个股当前信息,通过分析网页可发现,该板块是网页内嵌滚动数据,这个使用selenium中switch_to.frame函数获得,然后将所有获得的详细信息存入数据表二。
四、数据获取
1、个股行情
(1)配置本地数据库,用于存储数据
def mysql_login(): ###连接数据库,数据库配置
config = {
'host': 'localhost',
'port': 3306,
'user': '*******',
'password': '*******',
'db': 'mysql',
'charset': 'utf8',
'cursorclass': pymysql.cursors.DictCursor,
}
# Connect to the database
connection = pymysql.connect(**config)
return connection
(2)获取个股行情链接,存入数据表tonghuashun_lianjie_001
def get_url(): ##获得代码、名称以及url
connection=mysql_login()
hs='http://q.10jqka.com.cn/index/index/board/hs/field/zdf/order/desc/page/'
ss='http://q.10jqka.com.cn/index/index/board/ss/field/zdf/order/desc/page/'
zxb='http://q.10jqka.com.cn/index/index/board/zxb/field/zdf/order/desc/page/'
cyb='http://q.10jqka.com.cn/index/index/board/cyb/field/zdf/order/desc/page/'
zq_market=[hs,ss,zxb,cyb]
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36'}
j=0
for url in zq_market:
bk_list=get_url(url,j)
j+=1
bk_name=['hs','ss','zxb','cyb']
i=1
#print(bk_name[j])
#pages_all=2
while(1):
print(bk_name[j],i)
if i==1: ###抓第一页,获得总页数
urls=url+str(i)+'/ajax/1/'
browser=webdriver.Chrome(chrome_options=chrome_options)
browser.get(urls)
html_data2 = browser.page_source
browser.close()
root3 = etree.HTML(html_data2)
p=root3.xpath('//*[@id="m-page"]/span/text()')[0]
page_all=p[2:]
no_list=root3.xpath('/html/body/table/tbody/tr/td[1]/text()')
code_no=root3.xpath('/html/body/table/tbody/tr/td[2]/a/text()')
code_name=root3.xpath('/html/body/table/tbody/tr/td[3]/a/text()')
code_url=root3.xpath('/html/body/table/tbody/tr/td[2]/a/@href')
for no in range(len(code_url)):
sql = "INSERT INTO database.tonghuashun_lianjie_001 (bk_name,code_no,code_name,code_url,no) VALUES " \
"('" + bk_name[j] + "','" + code_no[no] + "','" + code_name[no] + "','" + code_url[no] + "','" + no_list[no] + "')"
with connection.cursor() as cursor:
cursor.execute(sql) ####存入数据库中
i+=1
if i>1 and i<=int(page_all):
urls=url+str(i)+'/ajax/1/'
browser=webdriver.Chrome(chrome_options=chrome_options)
browser.get(urls)
html_data2 = browser.page_source
browser.close()
root3 = etree.HTML(html_data2)
no_list=root3.xpath('/html/body/table/tbody/tr/td[1]/text()') # 序号
code_no=root3.xpath('/html/body/table/tbody/tr/td[2]/a/text()') # 企业代码
code_name=root3.xpath('/html/body/table/tbody/tr/td[3]/a/text()') #企业名称
code_url=root3.xpath('/html/body/table/tbody/tr/td[2]/a/@href') # 链接
for no in range(len(code_url)):
sql = "INSERT INTO database.tonghuashun_lianjie_001 (bk_name,code_no,code_name,code_url,no) VALUES " \
"('" + bk_name[j] + "','" + code_no[no] + "','" + code_name[no] + "','" + code_url[no] + "','" + no_list[no] + "')"
with connection.cursor() as cursor:
cursor.execute(sql) ####存入数据库中
i+=1
if i>int(page_all):
break
connection.commit()
2、公司简介及股值
(1)读取数据库表链接,获取个股股票代码、名称和url。
def get_url()
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
chrome_options.add_argument('--headless')
connection=mysql_login()
sql1='select distinct code_no,code_url,bk_name from database.tonghuashun_lianjie_001'
with connection.cursor() as cursor:
cursor.execute(sql1)
mm=cursor.fetchall()
code_no = [item['code_no'] for item in mm]
code_code_url=[item['code_url'] for item in mm]
code_market=[item['bk_name'] for item in mm]
connection.commit()
for i in range(385,len(code_code_url)):
stocks_content(i,code_no[i],code_code_url[i],code_market[i])
if i%50==0:
print(i,code_no[i])
(2)获取公司简介及股值。并存入数据库中
def stocks_content(i,code_no,url,code_market):
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36'}
###公司简介信息获取
web_data = requests.get(url,headers=headers)
root = etree.HTML(web_data.text)
name=root.xpath('//*[@id="in_squote"]/div/h1/a[1]/strong/text()')[0]
main_busin=root.xpath('/html/body/div[9]/div[2]/div[3]/dl/dd[4]/@title')[0].strip()
main_business=main_busin[:50]
company_details=root.xpath('//dd/text()')
####股票当前信息获取
browser2=webdriver.Chrome(chrome_options=chrome_options) ##内嵌网页内容提取
browser2.get(url)
browser2.switch_to.frame('ifm')
#ddd=browser.find_element_by_class_name('minus')
html_data2 = browser2.page_source
browser2.close()
root3 = etree.HTML(html_data2)
value_info=root3.xpath('//strong/text()')
all_ss=[name,company_details[0],company_details[3],company_details[4],company_details[5],
company_details[6],company_details[7],company_details[8],company_details[9],company_details[10],
company_details[11] ,company_details[12],company_details[13]]+value_info+[main_business]
####数据存入数据库
sql = "INSERT INTO database.tonghuashun_stocks_001 (no,item_no,market,item_name,area_loc,ipo_date, \ per_share_net_assets,per_share,net_profit,net_profit_growth_rate,operating_income,cash_flow_per_share,\ reserve_fund_per_share,udpps,capitalization,circulation_stock,today_price,today_volume,amplitude,max_price,\ turnover,turnover_rate,min_price,market_value,pbv,yesterday,circulattion_market_value,per,main_business) VALUES " \ "('" +str(i)+"','"+ code_no+"','"+ code_market+"','"+all_ss[0] + "','" + all_ss[1] + "','" +all_ss[2] + "','" + all_ss[3] + "','" + all_ss[4] + "','" + all_ss[5] + "','" \ +all_ss[6] + "','" +all_ss[7] + "','" + all_ss[8] + "','" + all_ss[9] +"','" + all_ss[10] +"','" + all_ss[11] +"','" + all_ss[12] +"','" \+all_ss[13] + "','" +all_ss[14] + "','" + all_ss[15] + "','" + all_ss[16] +"','" + all_ss[17] +"','" + all_ss[18] +"','" \
+all_ss[19] + "','" +all_ss[20] + "','" + all_ss[21] + "','" + all_ss[22] +"','" + all_ss[23] +"','" + all_ss[24] +"','" + all_ss[25] \
+ "')"
with connection.cursor() as cursor:
cursor.execute(sql)
connection.commit()
五、总结
本文使用python来爬取同花顺网上所有沪深上市公司基本信息以及当前市值信息,主要解决了异步数据获取和网页内嵌滚动信息获取两个问题。本次爬数总共获得目前沪深所有上市公司信息,共3540家:其中上海证券交易所上市公司总计1401家;深圳证券交易所上市公司总计2139家,其中主板457家、中小板925家、创业板757家。