Ⅰ.爬取数据的初衷:心血来潮,纯属娱乐,实战的过程其实也是探索的过程,难免冗余,多多包涵!

备注:

双色球是中国福利彩票的一种玩法。中国福利彩票“双色球”是一种由中国福利彩票发行管理中心统一组织发行,在全国销售联合发行的“乐透型”福利彩票。2003年2月16日起在全国联网销售。采用计算机网络系统发行销售,定期电视开奖。参与“双色球”销售的省级福利彩票发行中心在中福彩中心的直接领导下,负责对本地区的“双色球”销售活动实施具体的组织和管理。“双色球”彩票实行自愿购买,凡购买者均被视为同意并遵守本规则----来源:百度文库

,也是是说数据只从2003年开始喽!

Ⅱ.工具:

  1. 语言: python | sql
  2. 工具包:
    • urllib | pymysql | re | zlib
  3. 数据库:mysql

Ⅲ.网站页面分析

  1. 百度到这个网站数据http://kaijiang.500.com/ssq.shtml
  2. 页面分析,需提取的数据球号及期数
  3. 发现网页的规律:http://kaijiang.500.com/shtml/ssq/(期数).shtml
  4. 如何获取所有的期数呢?F12发现有个动态加载的div块这就好办了,直接复制这一整个div块,放到本地存为文件caipiao.html

总:网页规律和需要提取的数据也有了,接下来就是爬取和分析数据了

Ⅳ.数据库建表及技巧-mysql

CREATE TABLE `tb_dou_color` (`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',`red_one` int(2) DEFAULT NULL,`red_two` int(2) DEFAULT NULL,`red_three` int(2) DEFAULT NULL,`red_four` int(2) DEFAULT NULL,`red_five` int(2) DEFAULT NULL,`red_six` int(2) DEFAULT NULL,`blue` int(2) DEFAULT NULL,`period` varchar(100) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `peroid_uniq_index` (`period`) USING HASH COMMENT '期数唯一索引'
) ENGINE=InnoDB AUTO_INCREMENT=4613 DEFAULT CHARSET=utf8mb4 COMMENT='双色球数据';
解释一下:
1.主键自增
2.六个红色球号,一个蓝色球号,数据类型int,这里不设为varchar是为了防止网页结构不一致,爬到错误数据,让数据库协助去除错误数据
3.period 字段设置唯一索引 是为补救丢失数据,在重复爬取的时候去重

Ⅴ.爬虫代码伺候:

#读取本地之前保存的div块信息,提取所有的期数页面fh=open("c:/Users/nec/Desktop/caipiao.html","r")data=fh.read()#正则匹配pat='href="(.*?)"'import re#拿到页面listres=re.compile(pat).findall(data)len(res)

爬取过程中遇到ip被封杀,所以采用代理ip爬取

import urllib.request
#定义代理函数
def use_proxy(url,proxy_addr):proxy=urllib.request.ProxyHandler({"http":proxy_addr})print(proxy_addr)opener=urllib.request.build_opener(proxy,urllib.request.HTTPHandler)urllib.request.install_opener(opener)data=urllib.request.urlopen(url,timeout=8).read()return data

百度找到免费的代理ip,不是很稳定,但也还可以用
测试代理ip是否可用:

proxy_addr="112.85.128.47:9999"
html=use_proxy("http://www.baidu.com",proxy_addr)
112.85.128.47:9999

测试链接数据库:

import pymysql
conn=pymysql.connect(host="192.168.1.188",user="root",passwd="roota123",db="douball")
sql="show tables"
conn.query(sql)

爬取网页发现,网页优化做了gzip压缩,所以网页爬取后先需要解压缩
第一轮尝试爬取-异常处理后继续

import zlib
for url in res:try:print(url)#使用代理html=use_proxy(url,proxy_addr)#解压缩decompressed_data = zlib.decompress(html ,16+zlib.MAX_WBITS)#正则匹配pattern1='<li class="ball_red">(.*?)</li>'pattern2='<li class="ball_blue">(.*?)</li>'pattern3='<font class="cfont2"><strong>(.*?)</strong>'pattern4='<span class="span_right">(.*?)</span>'reds=re.compile(pattern1).findall(str(decompressed_data))blues=re.compile(pattern2).findall(str(decompressed_data))periods=re.compile(pattern3).findall(str(decompressed_data))print(reds[0])print(blues[0])print(periods[0])sql="insert into tb_dou_color (red_one,red_two,red_three,red_four,red_five,red_six,blue,period) values ("+reds[0]+","+reds[1]+","+reds[2]+","+reds[3]+","+reds[4]+","+reds[5]+","+blues[0]+","+periods[0]+")"conn.query(sql)#批处理提交if (periods[0]-1)%100==0:conn.commit()except Exception as err:print (err)

这个过程中出现了一些异常,丢失了部分数据

  1. 代理服务不可用
HTTP Error 503: Service Unavailable
http://kaijiang.500.com/shtml/ssq/19055.shtml
112.80.41.86:8888
  1. ip被封
<urlopen error [WinError 10061] 由于目标计算机积极拒绝,无法连接。>
http://kaijiang.500.com/shtml/ssq/19055.shtml112.85.128.209:9999
<urlopen error timed out>[WinError 10054] 远程主机强迫关闭了一个现有的连接。
http://kaijiang.500.com/shtml/ssq/18127.shtml
  1. 浏览器请求头异常等
Error -3 while decompressing data: incorrect header check
http://kaijiang.500.com/shtml/ssq/19054.shtml

所以需求适时切换代理ip,重复爬取数据,利用数据库唯一索引去重

(1062, "Duplicate entry '19052' for key 'peroid_uniq_index'")
http://kaijiang.500.com/shtml/ssq/19051.shtml
112.80.41.86:8888

适时手动提交一下数据

conn.commit()

代理请求函数添加浏览器伪装及指定网页压缩类型:

def use_proxy(url,proxy_addr):proxy=urllib.request.ProxyHandler({"http":proxy_addr})print(proxy_addr)opener=urllib.request.build_opener(proxy,urllib.request.HTTPHandler)urllib.request.install_opener(opener)headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:67.0) Gecko/20100101 Firefox/67.0",'Accept-Encoding':'gzip, deflate'}#opener=urllib.request.build_opener()#opener.addheaders=[headers]#data=urllib.request.urlopen(url,timeout=8).read()req=urllib.request.Request(url,headers=headers)data=urllib.request.urlopen(req).read()return data

优化后继续爬取数据:

for url in res:try:print(url)html=use_proxy(url,proxy_addr)try:decompressed_data = zlib.decompress(html ,zlib.MAX_WBITS|32)except Exception as err1:print (err1)try:decompressed_data = zlib.decompress(html ,zlib.MAX_WBITS|16)except Exception as err2:print (err2)try:decompressed_data = zlib.decompress(html)except Exception as err3:print(err3)decompressed_data = zlib.decompress(html,-zlib.MAX_WBITS)pattern1='<li class="ball_red">(.*?)</li>'pattern2='<li class="ball_blue">(.*?)</li>'pattern3='<font class="cfont2"><strong>(.*?)</strong>'pattern4='<span class="span_right">(.*?)</span>'reds=re.compile(pattern1).findall(str(decompressed_data))blues=re.compile(pattern2).findall(str(decompressed_data))periods=re.compile(pattern3).findall(str(decompressed_data))print(reds[0])print(blues[0])print(periods[0])sql="insert into tb_dou_color (red_one,red_two,red_three,red_four,red_five,red_six,blue,period) values ("+reds[0]+","+reds[1]+","+reds[2]+","+reds[3]+","+reds[4]+","+reds[5]+","+blues[0]+","+periods[0]+")"conn.query(sql)if (int(periods[0])-1)%100==0:conn.commit()except Exception as err:print (err)

爬到一大半,ip又被封了!

http://kaijiang.500.com/shtml/ssq/07098.shtml
112.85.171.116:9999
<urlopen error [WinError 10061] 由于目标计算机积极拒绝,无法连接。>
http://kaijiang.500.com/shtml/ssq/07097.shtml

切换ip,过滤已经爬取的部分,接着爬取

for url in res:patt="http://kaijiang.500.com/shtml/ssq/(.*?).shtml"index=re.compile(patt).findall(url)if int(index[0])>7098:continuetry:print(url)html=use_proxy(url,proxy_addr)try:decompressed_data = zlib.decompress(html ,zlib.MAX_WBITS|32)except Exception as err1:print (err1)try:decompressed_data = zlib.decompress(html ,zlib.MAX_WBITS|16)except Exception as err2:print (err2)try:decompressed_data = zlib.decompress(html)except Exception as err3:print(err3)decompressed_data = zlib.decompress(html,-zlib.MAX_WBITS)pattern1='<li class="ball_red">(.*?)</li>'pattern2='<li class="ball_blue">(.*?)</li>'pattern3='<font class="cfont2"><strong>(.*?)</strong>'pattern4='<span class="span_right">(.*?)</span>'reds=re.compile(pattern1).findall(str(decompressed_data))blues=re.compile(pattern2).findall(str(decompressed_data))periods=re.compile(pattern3).findall(str(decompressed_data))print(reds[0])print(blues[0])print(periods[0])sql="insert into tb_dou_color (red_one,red_two,red_three,red_four,red_five,red_six,blue,period) values ("+reds[0]+","+reds[1]+","+reds[2]+","+reds[3]+","+reds[4]+","+reds[5]+","+blues[0]+","+periods[0]+")"conn.query(sql)if (int(periods[0])-1)%100==0:conn.commit()except Exception as err:print (err)
conn.commit()

数据库查询数据量:

select count(*) from tb_dou_color

发现少了5条数据
筛选出遗漏的5条数据
先查出数据库已有的数据

sql1="select period from tb_dou_color"
#获取游标
cur=conn.cursor()
#执行查询
cur.execute(sql1)
#提取数据
rows=cur.fetchall()

将数据库提取到数据库封装到集合 arrs 中:

arrs=[]
for i in rows:print(i[0])arrs.append(i[0])

提取所有需要爬取的所有期数

arrays=[]
for i in res:patt="http://kaijiang.500.com/shtml/ssq/(.*?).shtml"print(i)ind=re.compile(patt).findall(i)b=int(ind[0])print(str(b))

将两个集合取差集,得到丢失了数据

div=list(set(array).difference(set(arrs)))
#['17001', '15081', '13091', '10119', '3069']

再次对丢失的数据爬取一次

for url in res:patt="http://kaijiang.500.com/shtml/ssq/(.*?).shtml"index=re.compile(patt).findall(url)if str(int(index[0])) not in div:continuetry:print(url)html=use_proxy(url,proxy_addr)try:decompressed_data = zlib.decompress(html ,zlib.MAX_WBITS|32)except Exception as err1:print (err1)try:decompressed_data = zlib.decompress(html ,zlib.MAX_WBITS|16)except Exception as err2:print (err2)try:decompressed_data = zlib.decompress(html)except Exception as err3:print(err3)decompressed_data = zlib.decompress(html,-zlib.MAX_WBITS)pattern1='<li class="ball_red">(.*?)</li>'pattern2='<li class="ball_blue">(.*?)</li>'pattern3='<font class="cfont2"><strong>(.*?)</strong>'pattern4='<span class="span_right">(.*?)</span>'reds=re.compile(pattern1).findall(str(decompressed_data))blues=re.compile(pattern2).findall(str(decompressed_data))periods=re.compile(pattern3).findall(str(decompressed_data))print(reds[0])print(blues[0])print(periods[0])sql="insert into tb_dou_color (red_one,red_two,red_three,red_four,red_five,red_six,blue,period) values ("+reds[0]+","+reds[1]+","+reds[2]+","+reds[3]+","+reds[4]+","+reds[5]+","+blues[0]+","+periods[0]+")"conn.query(sql)if (int(periods[0])-1)%100==0:conn.commit()except Exception as err:print (err)
conn.commit()

最后还剩一条网站丢失的数据,手动去查询其他网站,添加到数据库

(1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '{Result2},{Result3},{Result4},{Result5},{Result6},,17001)' at line 1")
http://kaijiang.500.com/shtml/ssq/15081.shtml
182.108.44.47:808

至此,数据全部爬取完成

Ⅵ.数据处理分析

import pandas as pd
k=pd.read_sql("select * from tb_dou_color",conn)
df=k.describe()id      red_one  ...      red_six         blue
count  2415.000000  2415.000000  ...  2415.000000  2415.000000
mean   1594.991304     4.751553  ...    28.925052     8.649689
std    1219.295142     3.701862  ...     3.777546     4.617859
min       1.000000     1.000000  ...    11.000000     1.000000
25%     606.500000     2.000000  ...    27.000000     5.000000
50%    1210.000000     4.000000  ...    30.000000     9.000000
75%    2749.500000     7.000000  ...    32.000000    13.000000
max    4610.000000    24.000000  ...    33.000000    16.000000df.to_csv('e:/python/code/res1.csv',index=False,header=False)

利用excel处理csv文件,进行进一步概率分析,利用excel 的rank等函数处理,得到最终结果:

未经允许,切勿扩散,Thanks♪(・ω・)ノ

福利彩票-双色球爬虫数据分析实战相关推荐

  1. 爬虫数据分析实战——腾讯视频《奔跑吧》第九季弹幕数据分析

    原文链接 淘宝搜券小助手上线啦,喜欢网购的你赶快来试试吧~!淘宝搜券微信机器人正在开发中,尽情期待!点击链接进入→淘宝搜券小助手 一.概述 1.数据来源 本次数据分析使用的数据来源腾讯视频的<奔 ...

  2. Python 爬虫和数据分析实战

    课程介绍 本课程以一个小项目带你快速上手 Python 爬虫和数据分析,主要分 3 部分: 第 1 部分是 Python 爬虫,主要使用 Urllib 3 和 BeautifulSoup 抓取天猫商城 ...

  3. python爬虫的应用-python网络爬虫应用实战

    原标题:python网络爬虫应用实战 Python这门编程语言包罗万象,可以说掌握了python,除了一些特殊环境和高度的性能要求,你可以用它做任何事. Python作为一门脚本语言,它灵活.易用.易 ...

  4. 爬虫技术实战 | WooYun知识库

    爬虫技术实战 | WooYun知识库 爬虫技术实战 大数据分析与机器学习领域Python兵器谱-大数据邦-微头条(wtoutiao.com) 大数据分析与机器学习领域Python兵器谱

  5. Python_数据分析_关联规则和王者荣耀数据分析实战

    如果同学不喜欢看理论,可以直接看后面王者数据分析的部分. 关联规则 如果不知道尿布和啤酒问题,建议百度百科,先有个大致的了解 我们找百度百科上面的例子来讲一下 tid是交易单号,后面每一纵列中1代表购 ...

  6. 数据分析实战----北京租房数据统计分析

    2.1 数据分析实战----北京租房数据统计分析 学习目标 掌握 Pandas的读写操作 会使用预处理技术过滤数据. 会使用 Matplotlib库绘制各种图表. 会基于数据进行独立分析. 近年来随着 ...

  7. python基础实例教程 微课版-Python爬虫开发实战教程(微课版)

    第1章 静态网页爬虫 1 1.1 爬虫的基本概念和工作原理 2 1.1.1 什么是网络爬虫 2 1.1.2 爬虫的结构与工作流程 3 1.2 爬虫抓包分析 4 1.2.1 使用Chrome浏览器进行抓 ...

  8. Python网络爬虫数据采集实战:Scrapy框架爬取QQ音乐存入MongoDB

    ​    通过前七章的学习,相信大家对整个爬虫有了一个比较全貌的了解 ,其中分别涉及四个案例:静态网页爬取.动态Ajax网页爬取.Selenium浏览器模拟爬取和Fillder今日头条app爬取,基本 ...

  9. bilibili爬虫+数据分析

    Python爬虫+数据分析+数据可视化实战 Python爬虫+数据分析+数据可视化实战 1. 背景介绍 2. 需求目标 3. 基于urllib的bangumi和bilibili一键爬虫脚本的编写 3. ...

  10. 腾讯弹幕数据分析实战

    腾讯弹幕数据分析实战 通用爬虫代码: 令人心动的offer2可视化分析 批量导入数据并合并 数据读取 数据处理及清洗 重命名 过滤字段 时间格式转换 机械压缩函数处理comment 会员等级打标 数据 ...

最新文章

  1. CStopWatch计时器的用法实例
  2. statistics DATA in jiangsu
  3. 台达plc控制伺服电机编程实例_PLC控制伺服电机:控制脉冲的相关计算
  4. DevExpress v18.1新版亮点——WPF篇(五)
  5. java 虚拟机 字节码,JAVA虚拟机:虚拟机字节码执行引擎
  6. WEB安全基础-PHP+MySQL实践
  7. java 图片上传_java web图片上传和文件上传实例
  8. 应用程序架构指导袖珍版
  9. hdfs 数据迁移_基于 JindoFS+OSS 构建高效数据湖
  10. Linux工作笔记024---Centos7 下查看本机公网IP
  11. LinkedList和 ArrayList的大数据面试资料(面试题)
  12. 使用 jQuery 和 KnockoutJS 开发在线股票走势图应用
  13. OpenCV python
  14. pikachu~~~验证码绕过(on client on server)
  15. 两轮电自2.0时代开启 小牛电动以独立主见创造新物种
  16. 如何搭建一个自己图床网站
  17. 【转载】VLOOKUP函数多条件查询 VLOOKUP三个条件查询
  18. 全量发布与灰度发布(APP版本发布)
  19. Java能够做哪些工作?这7个Java开发方向你知道几个?
  20. 【学习笔记】数据结构之单链表(先进先出、先进后出)

热门文章

  1. Rhino(犀牛)的视口
  2. Laravel 获取文件并保存
  3. 机器视觉在工业检测中的应用
  4. c语言fltk图形库,c-free-C/C++集成开发环境-c-free下载 v5.0官方版-完美下载
  5. Deeping Learning学习与感悟——《深度学习工程师》_5
  6. AlphaGo Zero算法讲解
  7. ADS学习:谐波分析和参数扫描
  8. c# MessageBox 用法大全
  9. wampserver下载安装使用教程
  10. FPGA的软件下载(百度盘~)