python爬虫实战(一)——利用BeautifulSoup爬取糗事百科

前言

酷安有个不错的安卓APP叫一句,可以以桌面插件的形式显示名人名言、诗词歌赋之类的,支持自定义文本。作为一个俗人,看到这个功能我虎躯一震,何不让它显示糗百呢?没事的时候可以看一看,图个乐。学习python也有一段时间了,正好可以练练手。
这是我写的第一个爬虫程序,写完一共也没花多少时间,把脚本共享出来,大家共同学习,欢迎指正。

准备

  • python版本:python3
  • 第三方库:requests, BeautifulSoup, lxml(可选)

开始

网址分析

糗百热门的首页地址为http://www.qiushibaike.com/hot/,第二页为http://www.qiushibaike.com/hot/page/2/,后面的都是这个格式。尝试http://www.qiushibaike.com/hot/page/1/,正常加载为首页,不出所料,这下就确定了网址格式。

网页内容分析

糗事大体分两种,带图片的和纯文字的,我们需要的是后者。查看网页源码可以发现,每条糗事都被包含在类似<div class="article block untagged mb15" id='qiushi_tag_118899109'>这种标签内,例如下面这条糗事:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div class="article block untagged mb15" id='qiushi_tag_118899109'>
......
<a href="/article/118899109" target="_blank" class='contentHerf' ><div class="content">


<span>杨姐,感谢你为国人讲述了西游记。美猴王、猪八戒、蜘蛛精等等,早已经融入了我的生活,后来拍的西游记,都无法和你相比!!给您点赞!!您走好!!</span>

</div></a>



<div class="thumb">
<a href="/article/118899109" target="_blank"><img src="//pic.qiushibaike.com/system/pictures/11889/118899109/medium/app118899109.jpg" alt="美猴王、猪八戒、蜘蛛精等等" /></a>
</div>


<div class="stats"><span class="stats-vote"><i class="number">1976</i> 好笑</span><span class="stats-comments">
......

<span>标签内的文本正是我们需要的内容。
通过分析其他糗事还可以知道,带图片的糗事,例如上面这条,多一个<div class="thumb">标签,纯文本的没有。那么我们找到<a href="/article/118899109" target="_blank" class='contentHerf'之后,判断它下一个标签是不是<div class="thumb">就可以排除图片糗事了。逻辑大概就是这样,比较简单,直接上代码了。如果你有效率更高的办法,欢迎提出来共同学习一下。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#!/usr/bin/python3

import requests
from bs4 import BeautifulSoup
from time import sleep


def get_qb(page_num):
'''
功能:获取糗事百科热门页面纯文字糗事
参数:page_num为需要获取的页数
返回值:list_qs 存放糗事的列表
'''
list_qs = [] # 存放糗事列表
url = 'http://www.qiushibaike.com/hot' # 糗百热门基础网址
for page in range(1, page_num + 1):
cnt = 0
qbhot = '{0}/page/{1}'.format(url, str(page))
print('开始获取第{0}页糗事...'.format(page), end=' ')
r = requests.get(qbhot)
soup = BeautifulSoup(r.text, 'lxml')
for tag in soup.find_all('a', class_='contentHerf'):
# 注意:tag.next_sibling是一个'\n'
if tag.next_sibling.next_sibling['class'] != ['thumb']:
list_qs.append(tag.div.span.get_text())
cnt += 1
print('{0}条'.format(cnt))
if page % 4 is 0:
sleep(0.5)
return list_qs


def main():
page_num = 10 # 想要获取的页数
file_qb = 'qiubai.txt' # 用于保存爬取回来的数据

ls_qs = get_qb(page_num)
with open(file_qb, 'w') as f:
f.write('\n'.join(ls_qs)) # 每条糗事保存一行

print('Done')


if __name__ == '__main__':
main()