网络爬虫(又被称为网页蜘蛛,网络机器人),是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁,自动索引,模拟程序或者蠕虫。
由于我经常看糗百,所以我突然想写个抓取糗百内容的爬虫,很多语言都可以写,我这里用Python来写,下面正式开始:
1.知己知彼,放能百战百胜
我们首先分析它的网页源码,找到内容和图片的那部分代码,像Chrome 、Firefox以及高版本的IE浏览器,都能够通过选中元素使用右键菜单迅速地帮助我们找到需要的代码:
2.备战
接下来我们开始获取数据,我先试探性地使用urllib.urlopen('http://www.qiushibaike.com/'),发现不能获取到数据,然后我又使用了多种手段,发现还是不行。于是我就猜测糗百会验证我们的请求头,但是urllib这个模块不能定义请求头信息,不过这个问题是小菜一碟,拿出神器urllib2,它可以定义请求头。通过测试我发现糗百会验证User-Agent这个请求头,这个请求头主要是用来设置浏览器的信息,我把User-Agent设置成了Chrome浏览器的信息,然后就顺利地获取到了数据,再通过测试,我发现它第一页的url是http://www.qiushibaike.com/8hr/page/1,第二页的是http://www.qiushibaike.com/8hr/page/2,以此类推。
3.万事俱备,只欠东风
有了前面的备战,我就能随心所欲的获取数据了,想怎么玩就怎么玩,现在我只需要内容和图片部分的数据,有很多种方式可以来截取,例如find函数、正则表达式。为了显得高大上,我选择了正则表达式来截取:
reg = r'<div class="content".+>\s+(.+)\s+</div>|src="(http://pic\.qiushibaike\.com/system/pictures.+?.jpg)"'
4.胜利
取到了特定的数据,最后我自己写了一个网页来显示这些数据。
下面是完整的源码:
import urllib2
import re
import sys
def getHtml(url):
'获取页面内容'
request = urllib2.Request(url)
request.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36')
return urllib2.urlopen(request).read()
def getArticle(html):
'获取内容和图片数据'
reg = r'<div class="content".+>\s+(.+)\s+</div>|src="(http://pic\.qiushibaike\.com/system/pictures.+?.jpg)"'
pattern = re.compile(reg)
article_list = re.findall(pattern, html)
return [(article.decode('utf-8'), img) for (article, img) in article_list]
def generateHtml(pageSize):
'在本地生成html页面'
for pageNum in range(1, pageSize + 1):
url = 'http://www.qiushibaike.com/8hr/page/' + str(pageNum)
article_list = getArticle(getHtml(url))
html = '<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<meta charset="utf-8"/>\n\t\t<title>糗百第' + str(pageNum) + '页</title>\n\t</head>\n\t<body>\n'
for (article, img) in article_list:
if article:
html += '\t\t<p>' + article + '</p>\n'
if img:
html += '\t\t<p><img src="' + img + '"/></p>\n'
html += '\n\t</body>\n</html>'
file = open(u'糗百第' + str(pageNum) + u'页.html', 'w')
file.write(html)
file.close()
#解决编码问题
stdout = sys.stdout
stdin = sys.stdin
stderr = sys.stderr
reload(sys)
sys.stdout = stdout
sys.stdin = stdin
sys.stderr = stderr
sys.setdefaultencoding('utf-8')
#开始
pageSize = raw_input(u'请输入获取前几页:'.encode('gbk'))
try:
generateHtml(int(pageSize))
print u'获取成功!'
except:
print u'输入有误!'
raw_input(u'\n按回车退出'.encode('gbk'))
生成的网页截图: