python爬取彩票排列三开奖结果

import gzip
import re
from urllib import request

import xlwt
from bs4 import BeautifulSoup


# 参数说明:
#   period: 开奖期数
#   redo_num: 重试次数,默认是0,每错误一次回调时会+1,默认就好
#   max:最大重试次数,默认5
def get_pls(period, redo_num=0, redo_max=5) -> dict:
    try:
        url = 'http://kaijiang.500.com/shtml/pls/%05d.shtml' % period
        req = request.Request(url)

        # 设置一下头,不设置返回结果不正确
        req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                                     'Chrome/79.0.3945.117 Safari/537.36')
        req.add_header('Accept',
                       'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,'
                       'application/signed-exchange;v=b3;q=0.9')
        req.add_header('Accept-Encoding', 'gzip')
        req.add_header('Accept-Language', 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7')
        req.add_header('Cache-Control', 'max-age=0')
        req.add_header('Host', 'kaijiang.500.com')
        req.add_header('Referer', 'http://kaijiang.500.com/shtml/pls/04001.shtml')
        req.add_header('Upgrade-Insecure-Requests', 1)
        req.add_header('Cookie',
                       'ck_regchanel=baidu; regfrom=0%7Cala%7Cbaidu; sdc_session=1579657460948; ')

        # 发送请求并读取结果
        html_content = request.urlopen(req).read()
        # 由于编码格式是gzip,所以需要进行解压
        html_content = gzip.decompress(html_content)
        # 解压后是一个bytes流,需要转换为字符串进行html解析
        html_content = html_content.decode('utf-8', errors='ignore')
        # 解析为soup构建的html对象
        soup = BeautifulSoup(html_content, 'html.parser')
        # 获取原始开奖号码(先定位到标签)
        pls_rst = soup.find_all('li', attrs={'class': 'ball_orange'})
        # 获取原始开奖期数
        qi_shu = soup.find_all('font', attrs={'class': 'cfont2'})
        # 获取原始开奖日期 - 截止兑奖日期
        pls_date = soup.find('span', attrs={"class": "span_right"})

        # 解析期数
        qi_shu = qi_shu[0].get_text() if qi_shu else period

        # 解析日期
        match_obj = re.findall(r'\d+', pls_date.get_text())
        # 开奖日期 解析不到取空
        start_date = match_obj[0] if match_obj else ''
        # 截止兑奖日期 解析不到取空
        end_date = match_obj[1] if match_obj else ''

        # 解析开奖号码
        # 第 1 位
        pls_1 = pls_rst[0].get_text()
        # 第 2 位
        pls_2 = pls_rst[1].get_text()
        # 第 3 位
        pls_3 = pls_rst[2].get_text()

        return {'period': qi_shu, 'num_1': pls_1, 'num_2': pls_2, 'num_3': pls_3, 'all': pls_1 + pls_2 + pls_3,
                'open_date': start_date, 'end_date': end_date}
    except OSError:
        # 达到最大请求次数,还是无法解压,则返回空
        if redo_num > redo_max:
            return {'period': qi_shu, 'num_1': '', 'num_2': '', 'num_3': '', 'all': '',
                    'open_date': '', 'end_date': ''}
        # 请求可能返回的结果不符合gzip格式所以这里做一下处理,不符合格式重新请求,一直到符合格式
        return get_pls(period, redo_num + 1)


'''
python 获取彩票【排列三】指定【期数区间】的的开奖号,并保存为Excel
需要用到的库: 
    BeautifulSoup:html解析从dom中获取需要的数据
    xlwt:Excel操作
    
    urllib.request:发送HTTP请求并接收结果
    re:正则表达式,提取字符串中的有效数据
    gzip:解压gzip格式的压缩数据
一次不要爬太多期哦,不然会很慢
'''
if __name__ == '__main__':
    l = []
    # 开始爬取的期数
    start = 4001
    # end = 20021
    # 结束爬取的期数
    end = 4020
    for q in range(start, end):
        rs = get_pls(q)
        l.append(rs)

    book = xlwt.Workbook()

    sheet = book.add_sheet('排列三')
    for index, head in enumerate(['期数', '第1位', '第2位', '第3位', '全部', '开奖日期', '兑奖截止日期']):
        sheet.write(0, index, head)

    row = 1
    for r in l:
        col = 0
        for key, value in r.items():
            sheet.write(row, col, value)
            col += 1
        row += 1

    book.save('排列三.xls')

欢迎关注公众号一起成长

### 使用Python爬取大量数据的最佳实践 为了高效地使用Python爬取大量数据(如一万条),需要综合考虑性能优化、稳定性以及法律合规性等问题。以下是几个关键方面: #### 1. **选择合适的库** 对于大规模数据抓取,推荐使用功能强大且高效的第三方库来完成任务。常用的库包括 `requests` 和 `aiohttp` 进行 HTTP 请求操作;`lxml`, `BeautifulSoup`, 或者 `PyQuery` 来解析 HTML 文档[^2]。 - 如果目标网站结构简单,则可采用同步方式通过 `requests` 获取页面用 `BeautifulSoup` 解析。 - 对于高发需求场景,异步框架如 `asyncio` 配合 `aiohttp` 是更好的解决方案,能够显著提升效率。 #### 2. **设置合理的请求间隔** 频繁访问服务器可能会被对方视为恶意行为而遭到封禁IP地址。因此,在编写程序时应加入随机等待时间以模拟人类浏览习惯,减少对目标站点的压力。可以通过如下代码实现简单的延时机制: ```python import time import random def sleep_random(): """休眠一段随机的时间""" t = random.uniform(0.5, 1.5) # 设置范围内的浮点数作为延迟秒数 time.sleep(t) ``` #### 3. **处理分页逻辑** 当面对包含海量记录的目标资源时,通常这些信息会被分成多个子页面展示出来。此时需注意分析URL模式变化规律或者API接口参数调整情况,从而构建完整的遍历路径。例如某些电商平台上商品列表可能按照每页显示固定数量的商品排列,那么就需要依次改变page number直至获取全部内容为止[^1]。 #### 4. **持久化存储策略** 考虑到内存占用问题以及防止因意外中断丢失已采集成果的情况发生,建议及时将中间结果保存至本地文件系统或其他形式的长储存介质当中。CSV是一种常见且易于管理的数据交换格式,可通过Scrapy框架配置轻松导出为该种类型文档[^5]。 另外还可以考虑关系型数据库(MySQL/PostgreSQL)或NoSQL方案(MongoDB/ElasticSearch),依据具体应用场景选取最适合的一种来进行后续数据分析工作前的数据积累过程。 #### 5. **异常捕获与重试机制** 网络环境复杂多变,难免会出现超时错误或者其他不可预见状况导致单次尝试失败的情形下仍能继续执行整体流程而不至于完全崩溃退出整个应用程序之外还需具备一定的容错能力即遇到临时性的障碍之后自动重新发起新一轮连接直到成功为止才停止进一步动作之前所采取措施之一便是引入try-except语句块包裹住核心业务部分以便捕捉可能出现的各种类型的Exception实例对象进而做出相应的响应动作比如打印日志消息通知开发者当前状态或者是稍后再做一次相同的调用命令等等具体情况视实际项目要求有所不同而已[^1]。 --- ### 示例代码片段 下面给出一个基于上述原则设计的小规模爬虫样例供参考学习之用: ```python import asyncio from aiohttp import ClientSession async def fetch(session, url): async with session.get(url) as response: return await response.text() async def main(urls): tasks = [] async with ClientSession() as session: for url in urls[:100]: # 控制发量大小 task = asyncio.ensure_future(fetch(session, url)) tasks.append(task) responses = await asyncio.gather(*tasks) return responses if __name__ == '__main__': loop = asyncio.get_event_loop() future = asyncio.ensure_future(main(['https://example.com'] * 100)) result = loop.run_until_complete(future) ``` 此段代码展示了如何利用 `asyncio` 实现非阻塞式的 I/O 操作,提高单位时间内所能完成的任务数目上限,非常适合用来应对大数据集下载的需求情境之中。 --- 问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值