0x01 Web数据挖掘类型
利用Python爬虫进行Web数据挖掘已经越来越普遍,网上的各种Python爬虫资料教程比较多,但是很少有人对Web数据挖掘进行系统地总结和分析。
从目标上来讲,Web数据挖掘分为三类。最常见的是对于网站内容的爬取,包括文本、图片和文件等;其次是对于网站结构的爬取,包括网站目录,链接之间的相互跳转关系,二级域名等;还有一种爬虫是对于Web应用数据的挖掘,包括获取网站CMS类型,Web插件等。
0x02 网站内容挖掘
网站内容挖掘应用最广,最为常见,网上的Python爬虫资料大多也都属于这类。爬取下的内容也可用于很多方面。
Python编写这类爬虫的常见思路就是利用request或urllib2库定制请求,利用BeautifulSoup对原始网页进行解析,定位特定html标签,寻找目标内容。如果要提高性能,可以利用threading启用多线程,gevent启用协程(在windows上使用可能会有些问题),也可以用multiprocessing启动多进程。multiprocessing能突破python的GIL全局解释器锁的限制。其他的一些技巧可以看我的另一篇博客:常见的反爬虫和应对方法
这类爬虫资料实在太多,在这里不再赘述了。
0x03 网站结构挖掘
网站结构挖掘并不是很常见,但在一些特殊的应用场景,我们也会用到。例如对于Web漏洞扫描器,爬取网站整站目录,获取二级域名是极为重要的。在第一类网站内容挖掘中,有时也需要将目标网站某个页面(通常是首页)作为入口,对整个网站所有内容进行获取和分析,这种情况下就需要对网站结构进行分析。
对于网站目录爬取,需要考虑的一个重要问题就是爬虫性能。通常网站的页面会比较多,如果直接获取所有目录,可能会耗费大量时间。另外,对于网站链接的搜索策略对爬虫的性能也会产生很大影响。一般情况下,我们会采用广度优先搜索,从入口页面开始,获取该页面内所有链接,并判断链接是否是站内链接,是否已经爬取过。为了提高速度,可以对链接进行归纳,将/page.php?id=1与/page.php?id=2认为是同一类型链接,不进行重复爬取。简单实现代码如下:
1 # coding=utf-8
2 '''
3 爬取网站所有目录
4 Author: bsdr
5 Email: 1340447902@qq.com
6 '''
7 import urllib2 8 import re 9 from BeautifulSoup import BeautifulSoup
10 import time 11
12 t = time.time()
13
14 HOST = ''
15 CHECKED_URL = [] # 已检测的url规则
16 CHECKING_URL = [] # 待检测的url
17 RESULT = [] # 检测结果
18 RETRY = 3 # 重复尝试次数
19 TIMEOUT = 2 # 超时
20
21
22 class url_node:
23 def __init__(self, url):
24 '''
25 url节点初始化
26 :param url: String, 当前url
27 :return:
28 '''
29 # self.deep = deep
30 self.url = self.handle_url(url, is_next_url=False)
31 self.next_url = []
32 self.content = ''
33
34
35 def handle_url(self, url, is_next_url=True):
36 '''
37 将所有url处理成标准格式
38
39 :param url: String
40 :param is_next_url: Bool, 判断传入的url是当前需要检测的url还是下一层url
41 :return: 返回空或错误信息或正确url
42 '''
43 global CHECKED_URL 44 global CHECKING_URL 45
46 # 去掉结尾的’/‘
47 url = url[0:len(url) - 1] if url.endswith('/') else url 48
49 if url.find(HOST) == -1:
50 if not url.startswith('http'):
51 url = 'http://' + HOST + url if url.startswith('/') else 'http://' + HOST + '/' + url 52 else:
53 # 如果url的host不为当前host,返回空
54 return
55 else:
56 if not url.startswith('http'):
57 url = 'http://' + url 58
59 if is_next_url:
60 # 下一层url放入待检测列表
61 CHECKING_URL.append(url)
62 else:
63 # 对于当前需要检测的url
64 # 将其中的所有参数替换为1
65 # 然后加入url规则表
66 # 参数不同,类型相同的url,只检测一次
67 rule = re.compile(r'=.*?\&|=.*?