前言
博主为python小白,前段时间买了一些彩票,出于对python爬虫的兴趣和记录发表了本篇抓取大乐透和双色球历史开奖数据的博客,由于本人水平有限,文中的代码比较繁琐和低级,关于一些专业性的东西表述也不是很规范,希望看到的大神多指教,同时也希望能帮到有需要的初学者!
使用的主要模块
requests、json、lxml、pandas
抓取大乐透历史开奖数据
抓取大乐透历史开奖数据使用的网站为中国体彩网:https://www.lottery.gov.cn/kj/kjlb.html?dlt.
分析思路
打开超级大乐透历史开奖页面,右键开奖数字进行审查元素,查看网页元素发现开奖数字储存在/html/body/div/div/table/tbody/tr中的td里面,然后尝试使用BeautifulSoup库的find方法或xpath语法获取td中的文本数据,多次尝试后发现获取的内容都为空,说明数据可能是储存在其他地方,并非此网页。
点击F12进入开发者工具,如下图进入网络下的XHR页面,然后对网页进行翻页操作,这时我们会发现每翻一次页就会出现一个新的XHR,打开请求的URL页面后查看后才发现该网站是通过Ajax加载json数据,每次进行翻页操作后网站加载对应的json数据。
到这里这终于知道了为什么通过BeautifulSoup库的find方法和Xpath语法都无法获取到开奖数据了,那最终选择翻页操作来获取所有历史数据。(这里吃了不懂HTML的亏啊,自己瞎捣鼓了一半天,开始还以为是自己语法有误!)
代码
抓取大乐透历史开奖数据代码:
#!user/bin/env python
# _*_ coding:utf-8 _*_
# _*_ author:taojinwnen _*_
import requests,collections,lxml,json,time
from lxml import etree
import pandas as pd
starttime = time.time()
#User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36
header = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36'}
#本次爬取使用的网站为中国体彩网:https://www.lottery.gov.cn/kj/kjlb.html?dlt
#多次查看后,所需的开奖数据储存在json文件中,以下为页数和前100的url
#https://webapi.sporttery.cn/gateway/lottery/getHistoryPageListV1.qry?gameNo=85&provinceId=0&pageSize=30&isVerify=1&pageNo=71
#url = 'https://webapi.sporttery.cn/gateway/lottery/getHistoryPageListV1.qry?gameNo=85&provinceId=0&pageSize=100&isVerify=1&pageNo=1&termLimits=100'
# 'lotteryDrawNum': '21011', 'lotteryDrawResult': '06 09 11 14 21 01 03',
# 'lotteryDrawStatus': 20, 'lotteryDrawTime': '2021-01-25'
columns = ['开奖日期', '期号', '前区', '后区']
data = {'开奖日期': '', '期号': '', '前区': '', '后区': ''}
data = collections.OrderedDict() # 定义为有序字典
dates = []
ids = []
front = [] #前区
behind = [] #后区
for pageNos in range(1,71):
url = 'https://webapi.sporttery.cn/gateway/lottery/getHistoryPageListV1.qry?gameNo=85&provinceId=0&pageSize=30&isVerify=1&pageNo={}'.format(pageNos)
#发送请求(获取json文件)
response = requests.get(url,headers = header)
content = response.content.decode('utf-8')
#使用lxml的etree解析html文件
html = etree.HTML(content)
js = json.loads(content)#json.loads 用于解码 JSON 数据。该函数返回 Python 字段的数据类型。
numbers = js.get('value')#获取js内储存所需要数据的字典
lists = numbers.get('list')#获取字典内的列表,但list内部还有30个字典储存着每一期的开奖数据(第一页开奖数据)
for shujudict in lists:
date = shujudict.get('lotteryDrawTime')
dates.append(date)
id = shujudict.get('lotteryDrawNum')
ids.append(id)
shuju = shujudict.get('lotteryDrawResult')
number = shuju.split(' ')
#qianqu = number[:5] #转为列表显示效果较差,有[]、'、,三种符号
#houqu = number[-2:]
qianqu = shuju[:14]
houqu = shuju[-5:]
front.append(qianqu)
behind.append(houqu)
data['开奖日期'] = dates
data['期号'] = ids
data['前区'] = front
data['后区'] = behind
df = pd.DataFrame(data,columns=columns)
df.to_excel('dlt.xlsx')
endtime = time.time()
time = endtime - starttime
print("耗时:",time,"秒")
#contents = html.xpath("//div[@class='g-history']/table[@class='m-historyTab']/tr/td/text()")
抓取双色球历史开奖数据
抓取双色球历史开奖数据使用的网站为开奖助手网:https://kjh.55128.cn/history_ssq.aspx
分析思路
吸取抓取大乐透历史开奖数据过程的经验,那第二次就简单多了,同样的打开超级双色球历史开奖页面,右键开奖数字进行审查元素,在弹出的元素页面中发现开奖日期和数字真的储存在//*[@id=“table”]/table/tbody/tr下的td和span,详见下图。
确定了数据储存的位置后,接着我们发现网页可以使用年份进行查询开奖结果,那我们最终使用lxml解析网页后,按年份进行循环使用Xpath语法获取历史开奖数据。
代码
抓取双色球历史开奖数据代码:
#!user/bin/env python
# _*_ coding:utf-8 _*_
# _*_ author:taojinwnen _*_
import requests,collections,lxml,time
from lxml import etree
import pandas as pd
starttime = time.time()
def list_to_string(list):
a = ' '.join(list)
columns = ['开奖日期', '期号', '红球', '蓝球']
data = {'开奖日期': '', '期号': '', '红球': '', '蓝球': ''}
data = collections.OrderedDict() # 定义为有序字典
dates = []
ids = []
reds = []
blues = []
header = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36'}
#尝试使用年份进行循环,该数据从2003年2月16日开始
for year in range(2021,2002,-1):
url = 'https://kjh.55128.cn/ssq-history-{}.htm'.format(year)
# 发送请求
response = requests.get(url, headers=header)
content = response.content.decode('utf-8')
# 使用lxml的etree解析html文件
html = etree.HTML(content)
trs = html.xpath('//table/tbody/tr')
shujus = len(html.xpath('//table/tbody/tr'))#查看tr的个数
for shuju in range(1,shujus):
#//table/tbody/tr[1]/td[1]/text() 开奖时间
#//table/tbody/tr[1]/td[2]/text() 期数
#//table/tbody/tr[1]/td[3]/span/text() 开奖号码
date = html.xpath('//table/tbody/tr[{}]/td[1]/text()'.format(shuju))
ISSUE = html.xpath('//table/tbody/tr[{}]/td[2]/text()'.format(shuju))
number = html.xpath('//table/tbody/tr[{}]/td[3]/span/text()'.format(shuju))
dates.append(' '.join(date)) #' '.join()方法将str类型的列表转换为字符串
ids.append(' '.join(ISSUE))
red = number[:6]
blue = number[-1:]
reds.append(' '.join(red))
blues.append(' '.join(blue))
data['开奖日期'] = dates
data['期号'] = ids
data['红球'] = reds
data['蓝球'] = blues
df = pd.DataFrame(data,columns=columns)
df.to_excel('ssq1.xlsx')
endtime = time.time()
time = endtime - starttime
print("耗时:",time,"秒")
使用xlwings库调整格式
xlwings - Make Excel Fly!
开始学习python操作Excel表发现有很多第三方库可以进行操作,比如xlrd/xlwt/xlutils、openpyxl、XlsxWriter、pyexcel等,在学习和使用了一段时间xlrd/xlwt后感觉不是不是很好用,在CSDN上看了各路大神对各个库对比分析后最终选择了xlwings库进行深入学习,以下代码为初步学习的一个尝试。
#!user/bin/env python
#_*_ coding:utf-8 _*_
#_*_ author:taojinwnen _*_
import xlwings as xw
wk = xw.Book('dlt1.xlsx')
sht1 = wk.sheets['sheet1']
#获取最后一个单元格
max = sht1.used_range.last_cell
#获取行列数
nrows = sht1.used_range.last_cell.row
nclos =sht1.used_range.last_cell.column
#设置对齐方式
sht1.range('A1:E2101').api.HorizontalAlignment = -4108 # -4108 水平居中。 -4131 靠左,-4152 靠右。
sht1.range('A1:E2101').api.VerticalAlignment = -4108 # -4108 垂直居中(默认)。 -4160 靠上,-4107 靠下, -4130 自动换行对齐。
#设置边框
sht1.range('A1').api.Borders(5).LineStyle = 1
sht1.range('A1').api.Borders(5).Weight = 3
sht1.range('A1:E2101').api.Borders(10).LineStyle = 1
sht1.range('A1:E2101').api.Borders(9).LineStyle = 1
#设置内部框线
sht1.range('A1:E2101').api.Borders(11).LineStyle = 1
sht1.range('A1:E2101').api.Borders(12).LineStyle = 1
#调整D2列宽至18
# sht.autofit() # 自动调整
sht1.range("D2").column_width = 18
#A1:E2101行高设为18
sht1.range('A1:E2101').row_height = 18
#隔行填充颜色
for nrow in range(2,nrows,2):
cell = 'A{}:E{}'.format(nrow,nrow)
#print(cell)
sht1.range(cell).color = (217,217,217)
lastrow = sht1.used_range.last_cell.row + 1
zhushi = 'A{}:E{}'.format(lastrow,lastrow)
sht1.range(zhushi).merge()
sht1.range(zhushi).value = '#_*_ author:taojinwnen _*_'
结语
以上就是对第一次尝试使用python抓取网页上自己感兴趣的数据并保存到Excel的过程的记录,希望大家彩票早日中奖!