写这篇文章纯属自娱自乐。
主要是近期在自学如何利用Python解决IT运维的一些问题时,总是不得其门而入,为了增加学习兴趣,就想通过完成一个小小有趣的爬虫程序激励下自己,同时也把这次经历跟各位道友分享下。
首先申明,本人不是专职coding的,所以,代码部分如果不符合专业审美,还请多多包涵;俺就是纯粹以实习那目标为基础的小白一枚;思路为先,抛砖引玉~
1. 打开百度搜索”彩票网”
第一个链接就是中彩网的官网;打开网站;在导航栏找到双色球并打开链接。
再找到开奖数据
找到往期回顾。
可以看到这就是我们需要获取的信息。
在网页上右击——>查看源代码或者直接按F12键。
借助浏览器我们很方便就可以得到网页的源码及网页中显示的数据对应的原始值。
接下来我们再看这个网页是不是就是简简单单的纯静态页面呢?怎么看呢?
1. 当前页面的网址(www.zhcw.com/ssq/kaijiangshuju/#)
2. 我们再点击下这个页面的下面几个位置
3. 看到其实他们的网址是不变的(www.zhcw.com/ssq/kaijiangshuju/#);这说明了什么?说明这些内容其实是嵌套在网页中网页文件。
那么问题来了?如何能获得嵌套网页的真实网址呢?这里我们还是要借助我们的浏览器工具(开发者工具F12)
先F12;找到Network;再单击页面山的“往期回顾”
得到这些交互数据:
凭经验(如果无经验或者经验不足,那就逐个文件查看)看这个list.html文件可能就是包含数据的最终文件了;查看该文件的预览。
哎呦,不错哦,猜中了;再看下上面途中第二个方框的Request URL部分的网址;这就是这个网页的真实网址了。
在浏览器打开这个网址试试看:
到这里我们才是真正的开始。
不妨我们随便单击下一页看看:
上一页
仔细看看网址的变化我们不妨大胆猜想下我们需要的数据是存放在以下internet路径上的:网址+_+页码+.html中。
验证下试试看,当前我这里显示有113页,不妨我试下访问:http://kaijiang.zhcw.com/zhcw/html/ssq/list_113.html
猜中了。
那接下来就按照这个真实的网址来抓取数据吧。
我们需要的数据是存放在:
<table>标签下的第4个以后的<tr>标签下;标签中包含:开奖日期/期号/蓝色中奖号码/红色中奖号码等信息。
步骤四:编写python代码
代码示例:
#!python3
import requests,bs4
def GetWinningInfo(webaddress):
res = requests.get(webaddress).text
htmlinfo = bs4.BeautifulSoup(res,‘html.parser‘)
resultinfo_qishu = htmlinfo.select(‘td‘)
resultinfo_haoma = htmlinfo.select(‘em‘)
#包括每一期的期号;开奖日期等信息
resultinfo_haomalist = str(resultinfo_haoma).replace(‘<em class="rr">‘,‘‘).replace(‘</em>‘,‘‘).replace(‘<em>‘,‘‘).replace(‘[‘,‘‘).replace(‘]‘,‘‘).split(‘,‘)
print(len(resultinfo_qishu))
for i in range(0,len(resultinfo_qishu)-1,7):
for j in range(0,2):
if j == 0:
print(‘开奖日期:‘ + str(resultinfo_qishu[i+j]).replace(‘<td align="center">‘,‘‘).replace(‘</td>‘,‘‘))
else:
print(‘期 号:‘ + str(resultinfo_qishu[i+j]).replace(‘<td align="center">‘,‘‘).replace(‘</td>‘,‘‘))
x = []
for n in range(0,7):
x.append(resultinfo_haomalist[i+n])
print(‘红色球:%s,%s,%s,%s,%s,%s;蓝色球:%s‘ % (x[0],x[1],x[2],x[3],x[4],x[5],x[6]))
#main
#TODO:获取总的页码数量
GetWinningInfo(‘http://kaijiang.zhcw.com/zhcw/html/ssq/list_1.html‘)
上面的代码目前仅实现了对第一页数据的正确获取并将获取的结果显示在屏幕上;到这里,本项目依然对现实生活起不到任何作用;当然除了给在座各位技术死宅们一丝丝窃喜~~~
因此,为了能让大多数人从本程序中的获益并由衷赞赏我们的超能力,我们还需要想的更多,做的更好。
例如:读取往期全部数据;将读取的数据保存在excel中;再对数据进行一些符合人类逻辑的分析,将分析结果展现在图表中等等……
首先我们实现抓取全部往期数据:
示例二:
#!python3
import requests,bs4
def GetWinningInfo(webaddress):
res = requests.get(webaddress).text
htmlinfo = bs4.BeautifulSoup(res,‘html.parser‘)
resultinfo_qishu = htmlinfo.select(‘td‘)
resultinfo_haoma = htmlinfo.select(‘em‘)
#包括每一期的期号;开奖日期等信息
resultinfo_haomalist = str(resultinfo_haoma).replace(‘<em class="rr">‘,‘‘).replace(‘</em>‘,‘‘).replace(‘<em>‘,‘‘).replace(‘[‘,‘‘).replace(‘]‘,‘‘).split(‘,‘)
print(len(resultinfo_qishu))
issuerDatas = []
for i in range(0,len(resultinfo_qishu)-1,7):
issuerData = []
for j in range(0,2):
if j == 0:
#print(‘开奖日期:‘ + str(resultinfo_qishu[i+j]).replace(‘<td align="center">‘,‘‘).replace(‘</td>‘,‘‘))
a = str(resultinfo_qishu[i+j]).replace(‘<td align="center">‘,‘‘).replace(‘</td>‘,‘‘)
issuerData.append(a)
else:
#print(‘期 号:‘ + str(resultinfo_qishu[i+j]).replace(‘<td align="center">‘,‘‘).replace(‘</td>‘,‘‘))
b = str(resultinfo_qishu[i+j]).replace(‘<td align="center">‘,‘‘).replace(‘</td>‘,‘‘)
issuerData.append(b)
x = []
for n in range(0,7):
x.append(resultinfo_haomalist[i+n])
#print(‘红色球:%s,%s,%s,%s,%s,%s;蓝色球:%s‘ % (x[0],x[1],x[2],x[3],x[4],x[5],x[6]))
issuerData.append(x)
issuerDatas.append(issuerData)
return issuerDatas
#main
#TODO:获取总的页码数量
numberOfPages = 113 #如果有兴趣可以尝试将这个数字也从网站中获取。
baseWebAddress = "http://kaijiang.zhcw.com/zhcw/html/ssq"
for e in range(1,numberOfPages+1):
print(‘--------这是第%s页--------‘ % e)
realWebAddress = baseWebAddress + ‘/list_‘+ str(e) + ‘.html‘
resultall = GetWinningInfo(realWebAddress)
for everyIssuerData in resultall:
#print(everyIssuerData)
print(‘【开奖日期】:%s‘ % everyIssuerData[0])
print(‘【期 号】:%s‘ % everyIssuerData[1])
print(‘【中奖号码】‘)
print(‘红色球:%s,%s,%s,%s,%s,%s;蓝色球:%s‘ % (everyIssuerData[2][0],everyIssuerData[2][1],everyIssuerData[2][2],everyIssuerData[2][3],everyIssuerData[2][4],everyIssuerData[2][5],everyIssuerData[2][6]))
以上代码实现了将往期所有开奖历史信息获取并打印到屏幕上的功能;接下来我们实现将获取的数据写入文件。
在开始下一步之前大家选需要掌握一些基础的python操作Excel文件的方法;这里我们加一个小插曲;一起学习下这方面的内容。(那我们就另加一个步骤吧。)
学习用Python处理Excel文件,这里主要用xlrd和xlwt模块,用前需要安装!一般就是要pip安装。(这个不会吗?那去查查谷歌吧。)
xlrd(excel read)来读取Excel文件,使用xlwt(excel write)来生成Excel文件(可以控制Excel中单元格的格式),需要注意的是,用xlrd读取excel是不能对其进行操作的:xlrd.open_workbook()方法返回xlrd.Book类型,是只读的,不能对其进行操作。而xlwt.Workbook()返回的xlwt.Workbook类型的save(filepath)方法可以保存excel文件。
因此对于读取和生成Excel文件都非常容易处理,但是对于已经存在的Excel文件进行修改就比较麻烦了。不过,还有一个xlutils(依赖于xlrd和xlwt)提供复制excel文件内容和修改文件的功能。其实际也只是在xlrd.Book和xlwt.Workbook之间建立了一个管道而已。
PS: xlwt、wlrd只能读写xls文件,而不能操作xlsx文件(道听途说,本人没有试过,想必是不会错的)
因此,我们需要用到openpyxl;安装非常简单也是用pip。(openpyxl只能操作xlsx文件而不能操作xls文件)
如果你还有图表的需求,那么你可以安装xlsxwriter库。
Python就是强大,兵器库已经由前辈们造好了;你只需要选择最合适的兵器;然后读一下使用说明;分分钟练就绝世神功;当然这个只适合速成班的同学们,真正要成为编程界的一代宗师,还是需要认真学学如何打造自己的趁手神兵的。
再辅一个差异对比的链接吧。
http://www.gocalf.com/blog/python-read-write-excel.html
https://zhuanlan.zhihu.com/p/23998083
我们先来看几个关于Excel的概念:
workbook: 每一个Excel文件就是一个workbook。
sheet: 每一个workbook中可以包含多个sheet,对应Excel中我们在左下脚所看到的“sheet1”,“sheet2”等。
cell: 每一个sheet就是我们通常所看到的一个表格,可以含有许多行和列,每个确定的行号,列号所对应的一个格子就是一个cell。
那么我就随便选择一个兵器:xlsxwriter(这货不能打开和修改现有的excel文件);虽然功能缺失了一些,但是应对我当前的需求足够了。
关于这个模块的深入学习,请参考这里:https://xlsxwriter.readthedocs.io/
首先是安装这个模块:pip install xlsxwriter
接下来尝试编写一个小小的脚本创建一个excel文件并在其中写入一些简单的数据。
下面给一个示例:
#!python3
import xlsxwriter
#本示例主要实现Excel文件的基本操作
#创建Excel文件
workbook = xlsxwriter.Workbook(‘testexcel.xlsx‘)
worksheet = workbook.add_worksheet(‘TEST‘)
workbook.close()
#读取现有的EXCEL文件的功能xlsxwriter模块无此功能,因此这里创建的文档和上面的不一样
workbook = xlsxwriter.Workbook(‘testexcel.xlsx‘)
worksheet = workbook.add_worksheet(‘TEST‘)
#设置列宽
worksheet.set_column(‘A:A‘,40)
worksheet.set_row(0, 40)
#自定义格式
bold = workbook.add_format({‘bold‘:True})
a = workbook.add_format({‘font_size‘: 26, ‘bold‘: True, ‘align‘: ‘left‘,‘bg_color‘: ‘cccccc‘})
b = workbook.add_format({‘border‘: 1, ‘font_size‘: 13, ‘bold‘: True, ‘align‘: ‘center‘,‘bg_color‘: ‘ccccc0‘})
worksheet.write(‘C1‘, "python excel")
worksheet.strings_to_urls
worksheet.write_row(‘H1‘,[‘X‘,‘X‘,‘X‘],b)
worksheet.write_row(‘H2‘,[‘X‘,‘X‘,‘X‘],b)
worksheet.write_row(‘H3‘,[‘X‘,‘X‘,‘X‘],b)
worksheet.write_row(‘H4‘,[‘X‘,‘X‘,‘X‘],b)
worksheet.write_row(‘H5‘,[‘X‘,‘X‘,‘X‘],b)
worksheet.write_row(‘H6‘,[‘X‘,‘X‘,‘X‘],b)
#A1单元格写入数据
worksheet.write(‘A1‘,‘Hello‘)
#B1单元格写入数据并加粗
worksheet.write(‘B1‘,‘World‘,bold)
#A2单元格写入数据并加粗
worksheet.write(‘A2‘,‘欢迎使用Python!‘,bold)
#另一种形式写入数据
worksheet.write(2,0,20)
worksheet.write(3,0,111.205)
#写入公式
worksheet.write(4,0,‘=SUM(A3:A4)‘)
#插入图片
worksheet.insert_image(‘A10‘, ‘11_test001.jpg‘)
worksheet.insert_image(‘A10‘, ‘11_test001.jpg‘, {‘url‘: ‘https://www.python.org/‘})
workbook.close()
有了以上这些最基础的知识以后,我们就可以继续去实现我们的想法了。
上面是一些题外话,下面进入正题;我们将在程序中添加代码,实现将抓取的数据写入EXCEL文件的目的,并且文件的命名方式为按照主题+日期的方式。
真实的环境下我们爬去数据不仅仅是为了拿而拿;关键还是的从数据中筛选分析出有用的信息。
直接上代码吧:
#!python3
import requests,bs4,xlsxwriter,time
#环境运行基础数据定义
#**********************************************************************
scriptRuningTime = time.strftime("%Y%m%d_%H%M%S", time.localtime())
outFileName = ‘LotteryHistoryDataList_‘ + scriptRuningTime + ‘.xlsx‘
baseWebAddress = "http://kaijiang.zhcw.com/zhcw/html/ssq"
#函数定义
#**********************************************************************
def GetWinningInfo(webaddress):
res = requests.get(webaddress).text
htmlinfo = bs4.BeautifulSoup(res,‘html.parser‘)
resultinfo_qishu = htmlinfo.select(‘td‘)
resultinfo_haoma = htmlinfo.select(‘em‘)
#包括每一期的期号;开奖日期等信息
resultinfo_haomalist = str(resultinfo_haoma).replace(‘<em class="rr">‘,‘‘).replace(‘</em>‘,‘‘).replace(‘<em>‘,‘‘).replace(‘[‘,‘‘).replace(‘]‘,‘‘).split(‘,‘)
#print(len(resultinfo_qishu))
issuerDatas = []
for i in range(0,len(resultinfo_qishu)-1,7):
issuerData = []
for j in range(0,2):
if j == 0:
#print(‘开奖日期:‘ + str(resultinfo_qishu[i+j]).replace(‘<td align="center">‘,‘‘).replace(‘</td>‘,‘‘))
a = str(resultinfo_qishu[i+j]).replace(‘<td align="center">‘,‘‘).replace(‘</td>‘,‘‘)
issuerData.append(a)
else:
#print(‘期 号:‘ + str(resultinfo_qishu[i+j]).replace(‘<td align="center">‘,‘‘).replace(‘</td>‘,‘‘))
b = str(resultinfo_qishu[i+j]).replace(‘<td align="center">‘,‘‘).replace(‘</td>‘,‘‘)
issuerData.append(b)
x = []
for n in range(0,7):
x.append(resultinfo_haomalist[i+n])
#print(‘红色球:%s,%s,%s,%s,%s,%s;蓝色球:%s‘ % (x[0],x[1],x[2],x[3],x[4],x[5],x[6]))
issuerData.append(x)
issuerDatas.append(issuerData)
return issuerDatas
#main
#**********************************************************************
#TODO:获取总的页码数量
numberOfPages = 113 #如果有兴趣可以尝试将这个数字也从网站中获取。
#创建Excel文件并写入表头
workbook = xlsxwriter.Workbook(outFileName)
worksheet = workbook.add_worksheet(‘Lottery‘)
worksheet.hide_gridlines(2)
tableHeader = ["NO.","开奖日期","期 号","红球1","红球2","红球3","红球4","红球5","红球6","蓝球1",]
a = workbook.add_format({‘border‘: 1, ‘font_size‘: 20, ‘bold‘: True, ‘align‘: ‘center‘,‘bg_color‘: ‘ccccc0‘})
b = workbook.add_format({‘border‘: 1, ‘font_size‘: 13,‘align‘: ‘left‘,‘bg_color‘: ‘5F9EA0‘})
c = workbook.add_format({‘border‘: 1, ‘font_size‘: 13,‘align‘: ‘left‘,‘bg_color‘: ‘D2B48C‘})
worksheet.write_row(‘A1‘, tableHeader,a)
#开始逐个网页爬取数据
i = 0
for e in range(1,numberOfPages+1):
print(‘--------这是第%s页--------‘ % e)
realWebAddress = baseWebAddress + ‘/list_‘+ str(e) + ‘.html‘
resultall = GetWinningInfo(realWebAddress)
for everyIssuerData in resultall:
i = i + 1
cellPos1 = ‘A‘ + str(i+1)
cellPos2 = ‘B‘ + str(i+1)
#小细节把抓取的数据写入前转换成数字格式
cellValue = [everyIssuerData[0],int(everyIssuerData[1]),int(everyIssuerData[2][0]),int(everyIssuerData[2][1]),int(everyIssuerData[2][2]),int(everyIssuerData[2][3]),int(everyIssuerData[2][4]),int(everyIssuerData[2][5]),int(everyIssuerData[2][6])]
if (i % 2) == 0:
worksheet.write(cellPos1,i,b)
worksheet.write_row(cellPos2, cellValue,b)
else:
worksheet.write(cellPos1,i,c)
worksheet.write_row(cellPos2, cellValue,c)
#增加一个Sheet
chartSheet = workbook.add_worksheet(‘Chart‘)
#增加一个折线图图表对象
chart_col = workbook.add_chart({‘type‘: ‘line‘})
name = ‘=%s!$J$1‘ % ‘Lottery‘
categories = ‘=%s!$B$2:$B$%s‘ % (‘Lottery‘,(i + 1))
values = ‘=%s!$J$2:$J$%s‘ % (‘Lottery‘,(i + 1))
print(‘%s|%s|%s‘ % (name,categories,values))
chart_col.add_series({
# 这里的sheet1是默认的值,因为我们在新建sheet时没有指定sheet名
# 如果我们新建sheet时设置了sheet名,这里就要设置成相应的值
‘name‘: name,
‘categories‘: categories,
‘values‘: values,
‘line‘: {‘color‘: ‘blue‘},
})
chart_col.set_title({‘name‘: ‘蓝色球分析‘})
chart_col.set_x_axis({‘name‘: ‘开奖日期‘})
chart_col.set_y_axis({‘name‘: ‘BlueNumber‘})
chart_col.set_style(1)
chartSheet.insert_chart(‘B2‘, chart_col)
chart_col.set_size({‘width‘: 10000, ‘height‘: 500})
workbook.close()
以上代码运行的结果是:
好了,到此我的目的基本实现,后面也许会尝试利用一些“运去”算法实现一些数据分析,看有没有时间了。
如果喜欢本文请给我点个赞,如果本文由什么纰漏,也请大家不吝赐教,共同进步~
文档和源码附件在:http://down.51cto.com/data/2445912
利用Python实现爬去彩票网站数据——小样
原文地址:http://blog.51cto.com/mlxia/2105244