用Python写爬虫程序获得煎蛋网上的段子

这段时间看了一些爬虫的程序,因此想可以写一个程序来爬取煎蛋网的段子栏目,这样就可以直接在命令行下面看段子,还可以过滤掉一些质量低的段子。

我们的爬虫程序需要定义一个Spider_Modelclass作为程序的主体,类包含以下的几个函数:

  1. __init__:一些变量的初始化。

  2. GetPage:根据要求的URL链接提取所有的段子添加到列表中并且返回列表

  3. LoadPage:如果当前已保存的页面小于2个,则调用GetPage获取新的页面

  4. ShowPage:根据需要的格式显示段子内容、赞数、反对数

  5. Start:程序从这里开始

煎蛋网段子的网址是以下这种形式的:

http://jandan.net/duan/page-328#comments

在程序中可以根据修改中间数字的而到达不同的页面。

为了能用Python来找出段子的位置,就要利用到正则表达式,在程序的开始要import re。首先查看一下网页源代码:

我们要用正则表达式匹配的内容从<div.*?class="text">开始,使用的表达式如下:

1
2
3
pattern ='<div.*?class="text"><span.*?class=".*?"><a.*?href=".*?">.*?</a>' + \
'</span><p>(.*?)</p>\s+<div.*?class="vote".*?cos_support-.*?">(\d+)</span>.*?cos_unsupport-.*?">(\d+)</span>]</div>'
myItems = re.findall(pattern, unicodePage, re.S)

这个正则表达式中包括三个括号,依次匹配的内容为段子的内容、oo数、xx数。匹配完成后,将这三项作为一个列表加入到名为items的列表中去。最后items将作为结果返回,这个列表中包含了一个页面中所有段子信息,它的每一个元素是由一条段子的内容、oo数、xx数组成的含有三个元素的列表。

1
2
3
for item in myItems:
text = item[0].replace("<br />", " ")
items.append([text, item[1], item[2]])

GetPage()函数的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def GetPage(self, page):

myUrl = "http://jandan.net/duan/page-" + page + "#comments"
user_agent = "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)"
headers = {'User-Agent' : user_agent}
req = urllib2.Request(myUrl, headers = headers)
myResponse = urllib2.urlopen(req)
myPage = myResponse.read()
unicodePage = myPage.decode('utf-8')

# re.s是任意匹配模式,也就是.可以匹配换行符
pattern ='<div.*?class="text"><span.*?class=".*?"><a.*?href=".*?">.*?</a>' + \
'</span><p>(.*?)</p>\s+<div.*?class="vote".*?cos_support-.*?">(\d+)</span>.*?cos_unsupport-.*?">(\d+)</span>]</div>'
myItems = re.findall(pattern, unicodePage, re.S)

items = []

# myItems中是包含一个页面内所有段子信息的list
# 每一个元素是一个元组,依次为段子内容、oo数、xx数
for item in myItems:
text = item[0].replace("<br />", " ")
items.append([text, item[1], item[2]])
return items

在显示段子时,程序会比较oo和xx的数值再加以输出。

完整的代码见GitHub项目