使用urllib进行网页爬取
# coding=gbk # 抓取开奖号码 # url:http://datachart.500.com/dlt/zoushi/jbzs_foreback.shtml ''' 对网页逐行迭代,找到目标行时在往下读一行,两行提取一期开奖号码 ''' import re from urllib import urlopen # winnumbers = {} # 期数:中奖号码 f = open('中奖号码.txt','w') webpage = urlopen('http://datachart.500.com/dlt/zoushi/inc/jbzs_foreback.php') for line in webpage: if re.search(r'^<td align="center">[\d\s]*</td>$',line.strip()): index = line.split('>')[1].split()[0] nextline = webpage.readline() numbers = re.findall(r'<td class="chartBall0[1,2]">([\d]+)',nextline) # winnumbers[index] = numbers print index,numbers f.write(index) for i in range(len(numbers)): f.write('\t') f.write(numbers[i]) f.write('\n') f.close()
结果如下:
首先用Chrome打开网页,利用审查元素功能找到真正的数据来源 http://datachart.500.com/dlt/zoushi/inc/jbzs_foreback.php
然后逐行迭代网页内容,利用正则表达式'<td align="center">[\d\s]*</td>'定位开奖期号:
然后使用 numbers = re.findall(r'<td class="chartBall0[1,2]">[\d]+',nextline) 找到开奖号码,对字符串处理一下得到开奖号码,存入列表。
这个时候 打印出来、存入字典、存入文件都可以。
这个方法不太好,可以直接把整个网页弄下来在本地处理。那样的话,写的正则就要复杂一点。鄙人刚刚学习正则,正在尝试中。
###################### 10月21日的分割线 ######################
按照上次最后提供的思路,把整个网页提取下来进行正则分析,代码如下
# coding=gbk # 抓取开奖号码 # url:http://datachart.500.com/dlt/zoushi/jbzs_foreback.shtml ''' 把整个网页爬取下来,然后使用re.findall定位目标数据 ''' import re from urllib import urlopen # winnumbers = {} # 期数:中奖号码 webpage = urlopen('http://datachart.500.com/dlt/zoushi/inc/jbzs_foreback.php') text = webpage.read() pattern = re.compile(r'<tr>\s*<td align="center">([\d\s]{6,})</td>\s*((?:<td class="(?:yl01|yl02|chartBall01|chartBall02)">\d+</td>){47})\s+</tr>') local = re.findall(pattern,text) for item in local: numbers = re.findall(r'<td class="chartBall0[1,2]">([\d]+)</td>',item[1]) print item[0].strip(), numbers # winnumbers[item[0]] = numbers
重点在于正则表达式的编写,我们需要一个正则表达式能够定位所有形如上图结构的html代码段。
最后测试得到了这样一段正则:
<tr>\s*<td align="center">([\d\s]{6,})</td>\s*((?:<td class="(?:yl01|yl02|chartBall01|chartBall02)">\d+</td>){47})\s+</tr>
它可以匹配到目标代码,编写遇到主要的困难在于提取,有两点很关键:
- 小括号表示要提取的内容,所以我们把[\d\s]{6,}括起来
- 但是有些小括号只表示整体,并非要提取的内容,这个时候就要在相应的表达式前面加上"?:",表示不提取这个括号中的内容
关于正则表达式中的括号,我们可以简单总结一下:
- 小括号:代表一个整体,例如(abc),它仅匹配字符串“abc”
- 中括号:表示取其中之一,例如[abc],它匹配“a”、“b”、“c”
- 大括号:表示重复次数,例如\d{1,3},它匹配一位到三位的数字