项目github地址:bitcarmanlee easy-algorithm-interview-and-practice
欢迎大家star,留言,一起学习进步
在网络上看到有介绍python爬虫爬去糗事百科段子的文章,觉得还挺好玩的,所以照着文章的思路自己重新实现了代码,完成了一个小小的爬虫爬取数据的例子。
1.抓取页面的源码
首先我们确定好页面的URL是 http://www.qiushibaike.com/hot/page/1,其中最后一个数字1代表页数,我们可以传入不同的值来获得某一页的段子内容。
首先来一段基本的页面抓取代码
def base_test():
page = 1
url = 'http://www.qiushibaike.com/hot/page/' + str(page)
try:
request = urllib2.Request(url)
response = urllib2.urlopen(request)
except urllib2.URLError,e:
if hasattr(e, "code"):
print e.code
if hasattr(e,"reason"):
print e.reason
base_test()
运行以后,代码坑坑报了一堆错:
...
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 453, in begin
version, status, reason = self._read_status()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 417, in _read_status
raise BadStatusLine(line)
httplib.BadStatusLine: ''
2.加入header信息
根据上面报的错,应该是header的原因。把header加上吧:
def base_test():
page = 1
url = 'http://www.qiushibaike.com/hot/page/' + str(page)
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = { 'User-Agent' : user_agent }
try:
request = urllib2.Request(url,headers=headers)
response = urllib2.urlopen(request)
print response.read()
except urllib2.URLError,e:
if hasattr(e, "code"):
print e.code
if hasattr(e,"reason"):
print e.reason
base_test()
运行代码,这次OK了,成功显示出来第一页的html代码,如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="X-UA-Compatible" content="chrome=1,IE=edge">
<meta name="renderer" content="webkit"/>
<meta name="applicable-device" content="pc">
<title>
...
后面还有很多内容,就不全贴了。
3.提取段子
为了方便查看网页的html代码,我们在页面任意位置右击,选择查看源代码,然后以某一个段子为例,看看他的html结构:
假设我们的目的是提取:1.段子的作者;2.段子的内容; 3.段子的点评数。对于第一个目的,被h2标签包围的就是作者,被div class="content"包围的是具体内容,被i class="number"包围的是点评数量。
采用正则的方式,可以分别将以上我们感兴趣的内容提取出来:
def parse_html():
page = 1
url = 'http://www.qiushibaike.com/hot/page/' + str(page)
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = { 'User-Agent' : user_agent }
try:
request = urllib2.Request(url,headers = headers)
response = urllib2.urlopen(request)
content = response.read().decode('utf-8')
pattern_author = re.compile(u'<h2>(.*?)</h2>',re.S)
pattern_content = re.compile(u'<div class="content">(.*?)</div>',re.S)
pattern_comment = re.compile(u'<i class="number">(\d*)</i>\s*评论',re.S)
find_author = re.findall(pattern_author,content)
find_content = re.findall(pattern_content,content)
find_comment = re.findall(pattern_comment,content)
if find_author:
for i in xrange(len(find_author)):
result = str(i)+" "+find_author[i]+" "+find_content[i]+" "+str(find_comment[i])
print result
except urllib2.URLError, e:
if hasattr(e,"code"):
print e.code
if hasattr(e,"reason"):
print e.reason
parse_html()
如果对正则不是很熟的同学,可以参考以下:
- ".“是通配符,”*“表示匹配0次或任意次,”?"表示非贪婪匹配,.*?组合在一起则表示尽可能短地做匹配。
- (.*?)代表一个分组,或者说一个捕获组。
- re.S 标志代表在匹配时为点任意匹配模式,点 . 也可以代表换行符。
上面我们通过三个正则表达式分别找出了发帖人,内容以及点评数。
让代码运行起来:
0 郭思雨
真事!昨天公司组织开会。领导说带好你们吃饭的家伙到办公室集合。结果到办公室一看同事们都带着笔记本。而我特么却拿了一个碗。
348
1 王医森
不愧是母女仨儿
1
2 onepiece美凌格
最近好多人来这个贴左下,为了方便大家我再发一次<br/>专捉小人,速速左下让小人远离你!
66
...
##4.修改正则,使结果更美观
观察上面结果,再结合之前的html源码,发现结果不是很美观,主要是由于空格与换行符引起的。为此,我们修改一下代码:
def parse_html():
page = 1
url = 'http://www.qiushibaike.com/hot/page/' + str(page)
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = { 'User-Agent' : user_agent }
try:
request = urllib2.Request(url,headers = headers)
response = urllib2.urlopen(request)
content = response.read().decode('utf-8')
pattern_author = re.compile(u'<h2>(.*?)\s*</h2>',re.S)
pattern_content = re.compile(u'<div class="content">\s*(.*?)\s*</div>',re.S)
pattern_comment = re.compile(u'<i class="number">(\d*)</i>\s*评论',re.S)
find_author = re.findall(pattern_author,content)
find_content = re.findall(pattern_content,content)
find_comment = re.findall(pattern_comment,content)
if find_author:
for i in xrange(len(find_author)):
content= find_content[i].replace("<br/>",",")
result = str(i)+" "+find_author[i]+" "++" "+str(find_comment[i])
print result
except urllib2.URLError, e:
if hasattr(e,"code"):
print e.code
if hasattr(e,"reason"):
print e.reason
parse_html()
改动主要有两处:
1.将匹配处的空格去除,不在捕获组里。
2.将内容中的br换行标签去除。
最后的结果:
0 郭思雨 真事!昨天公司组织开会。领导说带好你们吃饭的家伙到办公室集合。结果到办公室一看同事们都带着笔记本。而我特么却拿了一个碗。 352
1 王医森 不愧是母女仨儿 1
2 onepiece美凌格 最近好多人来这个贴左下,为了方便大家我再发一次,专捉小人,速速左下让小人远离你! 66
3 院长!放我出院! 我爸的网名:点点爸,我妈的网名:点点妈,不知道的都以为我叫点点,点点其实是我家的狗! 447
4 .似水年华 夏天到了 天气很热 许多男孩包括我喜欢把体恤向上卷起来 漏出脊背凉快 但是 我要说的是一些吨位较大的男生 把体恤提到胃部左右立刻 不要再往上漏出咪咪 这是对一些平胸妹子最基本尊重!!! 151
5 帅哥之神 谁被占便宜了 8
6 陌上芊芊蔚 老公在看书,我在看糗百,他瞅了我一眼,说:你能看点有营养的吗。。。。,我说:好啊!!,于是我默默的打开了淘宝。,没一会儿,他回过头跟我说:你还是看糗百吧,省钱。。。。。。 23
7 我是个小耳朵 我们寝室一起出去找兼职,走到小吃店,人家问要吃点什麽,我还没来得及问要不要找兼职,那几个人就纷纷报出了自己要吃的东西。。尼玛,本性难移 10
8 仅存~执念 今天是我们结婚10周年纪念日,想到老公以前写的情书经常有:“我心里有个小兔子在乱撞呢。”,问他:“老公,你心里的那个小兔子呢?”老公:“早撞死了!” 37
9 一顶砖 大哥你这么怒气冲冲的是要去替天行道吗?~ 19
10 丢了自己的百毒 学霸老妹跟同学出去逛街,回来买了好多东西,我:你都没带多少钱,怎么能买这么多东西?,老妹:她们天天抄我作业,所以我不管买什么东西,她们都抢着付钱~,书中自有黄金屋,古人诚不欺我…… 40
11 小斐之家成人用品 夏天和老爸一起去吃饭,吃了俩王八,又喝了一箱啤酒。结账的时候,老板娘问服务员:“他们吃了什么?”那服务业说:“俩王八喝了一箱啤酒。”然后,老板娘只算了啤酒的钱,王八钱没算。 123
12 隔壁伱王叔 某日晚上,护城河边有一女子欲寻短见,围观者众。突然有一男子奋不顾身,跃入两米深的河中救人,众人正为此人义举赞赏不已。岂知,那男子心急火燎地游至女子身边一看,啊,不是我老婆啊! 25
13 封存の记忆 大学的时候,有个老师讲课极其无聊,有一次他讲到一半的时候我突然醒了,因为想起来校长坐我旁边听课,---扭头一看,校长睡着了.... 67
14 取什么名儿++/呢 我妈让我不要跟学习比我差的同学玩,于是我去找学习委员。学习委员说:“我妈不让我跟学习比我差的同学玩”。 115
15 黄88 就剩下二百块钱了,我躺床上想了一天,这二百块钱怎么才能坚持花到发工资,现在好了,不用想了!我特么把钱丢了!!! 190
16 冰是睡着的水21 老婆的闺密很时尚!一天来我家看到我女儿打扮的不潮,就喊着老婆带着孩子去了理发店,烫了个发~染了个颜色!,结果第二天上课:女儿被校长留在了办公室!还要叫家长!!尼玛的时尚出事了吧! 38
17 大大白萝卜 上初中的时候,都喜欢看电子书,背景,当时看的是都市小说,里面有段啪啪,上课看着看着年轻漂亮的英语老师下来了,搞的手忙脚乱把手机塞到书底下,不知道咋的点了语音读书,然后就听见啊……恩……轻点……痛……然后就没了 53
18 啊喂、切克闹 旅馆走廊上,挂着一块牌子,上面写着:“请夜间保持安静,切勿打扰旅客休息。”,第二天早晨,人们发现牌子上这行字的下面又添了一行小字:“要是老鼠也认字,那该多好!” 36
19 跳舞的袜子 大学时候睡上铺的哥们喜欢同班的一姑娘,跑去要号码,那女孩把班长的号码给了他,结果两爷们短信聊了一学期.... 174
这样就比较清晰了。怎么样,很酷吧!