Python爬虫进行Web数据挖掘总结和分析 这是我见过最牛逼的教程_基于python的网络爬虫及数据挖掘项目_冠亦Python的博客-程序员秘密

技术标签: 爬虫  python  自动化  数据挖掘  

利用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认为是同一类型链接,不进行重复爬取。简单实现代码如下:

image

1 # coding=utf-8

2 ‘’’

3 爬取网站所有目录

4 Author: bsdr

5 Email: [email protected]

6 ‘’’

7importurllib2

8importre

9fromBeautifulSoupimportBeautifulSoup

10importtime

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

22class****url_node:

23def****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

35def****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 ‘’’

43globalCHECKED_URL

44globalCHECKING_URL

45

46 # 去掉结尾的’/‘

47 url = url[0:len(url) - 1]ifurl.endswith(’/’)elseurl

48

49ifurl.find(HOST) == -1:

50if****noturl.startswith(‘http’):

51 url = ‘http://’ + HOST + urlifurl.startswith(’/’)else’http://’ + HOST + ‘/’ + url

52else:

53 # 如果url的host不为当前host,返回空

54return

55else:

56if****noturl.startswith(‘http’):

57 url = ‘http://’ + url

58

59ifis_next_url:

60 # 下一层url放入待检测列表

61 CHECKING_URL.append(url)

62else:

63 # 对于当前需要检测的url

64 # 将其中的所有参数替换为1

65 # 然后加入url规则表

66 # 参数不同,类型相同的url,只检测一次

67 rule = re.compile(r’=.?&|=.?$’)

68 result = re.sub(rule, ‘=1&’, url)

69ifresultinCHECKED_URL:

70return’[!] Url has checked!’

71else:

72 CHECKED_URL.append(result)

73 RESULT.append(url)

74

75returnurl

76

77

78def****__is_connectable(self):

79 # 验证是否可以连接

80 retry = 3

81 timeout = 2

82foriinrange(RETRY):

83try:

84 response = urllib2.urlopen(self.url, timeout=TIMEOUT)

85return****True

86except:

87ifi == retry - 1:

88return****False

89

90

91def****get_next(self):

92 # 获取当前页面所有url

93 soup = BeautifulSoup(self.content)

94 next_urls = soup.findAll(‘a’)

95iflen(next_urls) != 0:

96forlinkinnext_urls:

97 self.handle_url(link.get(‘href’))

98

99

100def****run(self):

101ifself.url:

102printself.url

103ifself.__is_connectable():

104try:

105 self.content = urllib2.urlopen(self.url, timeout=TIMEOUT).read()

106 self.get_next()

107except:

108 print(’[!] Connect Failed’)

109

110

111class****Poc:

112def****run(self, url):

113globalHOST

114globalCHECKING_URL

115 url = check_url(url)

116

117if****noturl.find(‘https’):

118 HOST = url[8:]

119else:

120 HOST = url[7:]

121

122forurlinCHECKING_URL:

123 print(url)

124 url_node(url).run()

125

126

127def****check_url(url):

128 url = ‘http://’ + urlif****noturl.startswith(‘http’)elseurl

129 url = url[0:len(url) - 1]ifurl.endswith(’/’)elseurl

130

131foriinrange(RETRY):

132try:

133 response = urllib2.urlopen(url, timeout=TIMEOUT)

134returnurl

135except:

136raiseException(“Connect error”)

137

138

139ifname == ‘main’:

140 HOST = ‘www.hrbeu.edu.cn’

141 CHECKING_URL.append(‘http://www.hrbeu.edu.cn/’)

142forurlinCHECKING_URL:

143 print(url)

144 url_node(url).run()

145printRESULT

146print"URL num: "+str(len(RESULT))

147print"time: %d s" % (time.time() - t)

对于二级域名的获取,如果直接从主站爬取的链接中寻找,效率很低而且结果可能并不能让人满意。目前获取二级域名有三种常用方法,第一种是利用域名字典进行猜解,类似于暴力破解。最后,如果你的时间不是很紧张,并且又想快速的python提高,最重要的是不怕吃苦,建议你可以架尉信(同音):276 3177 065 ,那个真的很不错,很多人进步都很快,需要你不怕吃苦哦!大家可以去添加上看一下~
第二种种是利用各种二级域名查询接口进行查询,例如bing的查询接口如下,domain为根域名:

http://cn.bing.com/search?count=50&q=site:domain&first=1

link的二级域名查询接口为:

http/i.links.cn/subdomain/?b2=1&b3=1&b4=1&domain=domain

aleax的二级域名查询接口为:

http/alexa.chinaz.com/?domain=domain

由这些接口都能直接查询到指定根域名的二级域名,这里就不附代码了。

还有一种获取二级域名的方法是通过搜索引擎直接搜索,如百度搜索:inurl:domain 或 site:domain。这种方法比较慢。具体代码如下:

1 # coding=utf-8

2 ‘’’

3 利用百度搜索二级域名

4 Author: bsdr

5 Email:[email protected]

6 ‘’’

7

8

9importurllib2

10importstring

11importurllib

12importre

13importrandom

14fromurl_handleimportsplit_url

15

16 user_agents = [‘Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20130406 Firefox/23.0’,

17 ‘Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0’,

18 ‘Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533+ (KHTML, like Gecko) Element Browser 5.0’,

19 ‘IBM WebExplorer /v0.94’, ‘Galaxy/1.0 [en] (Mac OS X 10.5.6; U; en)’,

20 ‘Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)’,

21 ‘Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14’,

22 ‘Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25’,

23 ‘Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36’,

24 ‘Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0; TheWorld)’]

25

26

27def****baidu_search(keyword,pn):

28 p= urllib.urlencode({‘wd’:keyword})

29 print§

30 req = urllib2.Request((“http://www.baidu.com/s?”+p+"&pn={0}&cl=3&rn=10").format(pn))

31 req.add_header(‘User-Agent’, random.choice(user_agents))

32try:

33 res=urllib2.urlopen(req)

34 html=res.read()

35except:

36 html = ‘’

37returnhtml

38

39

40def****getList(regex,text):

41 arr = []

42 res = re.findall(regex, text)

43ifres:

44forrinres:

45 arr.append

46returnarr

47

48

49def****getMatch(regex,text):

50 res = re.findall(regex, text)

51ifres:

52returnres[0]

53return’’

54

55

56def****is_get(url):

57

58 regex=r’(S*?)?.=.

59 res=re.match(regex,url)

60ifres:

61returnres.group(1)

62else:

63return0

64

65

66def****geturl(domain,pages=10):

67 keyword = ‘site:.’+domain

68 targets = []

69 hosts=[]

70forpageinrange(0,int(pages)):

71 pn=(page+1)*10

72 html = baidu_search(keyword,pn)

73 content = unicode(html, ‘utf-8’,‘ignore’)

74 arrList = getList(u"

(.*)
", content)

75

76foriteminarrList:

77 regex = u"data-tools=’{“title”:"(.)",“url”:"(.)"}’"

78 link = getMatch(regex,item)

79 url=link[1]

80try:

81 domain=urllib2.Request(url)

82 r=random.randint(0,11)

83 domain.add_header(‘User-Agent’, user_agents[r])

84 domain.add_header(‘Connection’,‘keep-alive’)

85 response=urllib2.urlopen(domain)

86 uri=response.geturl()

87 urs = split_url.split(uri)

88

89if(uriintargets)or(ursinhosts) :

90continue

91else:

92 targets.append(uri)

93 hosts.append(urs)

94 f1=open(‘data/baidu.txt’,‘a’)

95 f1.write(urs+’ ')

96 f1.close()

97except:

98continue

99print"urls have been grabed already!!!"

100returnhosts

101

102

103ifname == ‘main’:

104 print(geturl(“cnblogs.com”))

0x04 Web应用数据挖掘

这种数据挖掘方式主要针对Web自身,旨在获取Web应用信息/Web指纹,在Web安全领域应用较多,这类代表有zoomeye、sodan等。通过获取大范围的Web应用信息,Web应用类型、版本,Web插件信息等,能够对大范围内的Web安全状况进行评估,分析特定漏洞在全球范围内造成的影响。当然也可以利用特定漏洞对大范围的Web应用进行定向攻击。

在这里我们不讨论那种大范围的扫描,我们只以CMS识别为例来简单说明Web应用数据的挖掘。CMS识别旨在判别网站所采用的CMS(内容管理系统,如WordPress),为后续的插件检测或漏洞检测做准备。

CMS识别一般从4个方面进行检测:检测特定目录是否存在;比对特定文件MD5;检测HTML页面中的关键字;检测robots文件。另外,一个巨大的CMS指纹库是保证识别效率的关键,如果指纹库太小,实际效果并不会很好。但是如果指纹库太大,又会影响到识别的速率。我搜集了一些简单的CMS指纹,写了一个简单的CMS识别脚本。代码如下:

1 # coding:utf-8

2 ‘’’

3 CMS识别

4 Author: bsdr

5 Email: [email protected]

6 ‘’’

7importQueue

8importre

9importos

10importtime

11importrequests

12importthreading

13importurllib2

14importhashlib

15importsys

16fromconfigimportPOC_PATH

17

18 t = time.time() # 起始时间

19

20 event = threading.Event() # 全局event,用来控制线程状态

21

22 RETRY = 3 # 验证url时尝试次数

23 TIMEOUT = 3 # 超时

24 THREADS = 300 # 开启的线程数

25 CMS_PATH = os.path.join(POC_PATH, ‘CMS2’) # CMS指纹文件目录

26

27 CMS = ‘Unknown’

28 HEADER = {‘User-Agent’: 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ’

29 ‘en-US; rv:1.9.1.11) Gecko/20100701 Firefox/3.5.11’}

30

31

32class****Cms:

33def****init(self, url, line):

34 self.url = url

35 self.line = line

36printline

37

38

39 # 检测文件md5

40def****_get_md5(self, file):

41 m = hashlib.md5()

42

43try:

44 m.update(file)

45except:

46while****True:

47 data = file.read(10240) # 避免文件太大,内存不够

48if****notdata:

49break

50 m.update(data)

51

52returnm.hexdigest()

53

54

55 # 检测每一行指纹

56def****check(self):

57globalCMS

58globalevent

59 cms = re.findall(r’(.*?)|’, self.line)

60 path = cms[0]

61 cms_name = cms[1]

62 keyword = cms[2]

63 content = ‘’

64

65try:

66 response = requests.get(self.url+path)

67ifresponse.status_code == 200:

68 content = response.content

69except:

70try:

71 content = urllib2.urlopen(self.url+path, timeout=TIMEOUT).read()

72except:

73pass

74

75ifcontentisnotNone****andcontent != ‘’:

76

77iflen(cms) == 3andcontent.find(keyword) != -1:

78 CMS = cms_name

79printcms

80 event.set() # 识别出cms后,改变event状态

81

82eliflen(cms) == 4andself._get_md5(content) == cms[3]:

83 CMS = cms_name

84 event.set()

85printcms

86

87

88

89 # 创建线程类,定义自己的线程

90class****myThread(threading.Thread):

91def****init(self, q, thread_id):

92 threading.Thread.init(self)

93 self.q = q

94 self.thread_id = thread_id

95

96

97def****run(self):

98globalevent

99while****notself.q.empty():

100 # 检测event状态判断线程是否执行

101ifevent.is_set():

102print" [+] stop threading " + str(self.thread_id)

103break

104print" [*] threading " + str(self.thread_id) + " is running"

105 objects = self.q.get()

106 objects.check()

107

108

109 # 初始化url,并验证是否可以连接

110def****check_url(url):

111 url = ‘http://’ + urlifurl.startswith(‘http’) ==False****elseurl

112 url = url[0:len(url) - 1]ifurl.endswith(’/’)elseurl

113

114foriinrange(RETRY):

115try:

116 response = urllib2.urlopen(url, timeout=TIMEOUT)

117ifresponse.code == 200:

118returnurl

119except:

120raiseException(“Connect error”)

121

122

123 # 遍历指定目录下所有文件的每一行

124def****load_cms():

125 cms_list = []

126

127forroot, dirs, filesinos.walk(CMS_PATH):

128forfinfiles:

129 fp = open(CMS_PATH + f, ‘r’)

130 content = fp.readlines()

131 fp.close()

132forlineincontent:

133ifline.startswith(’/’):

134 line = line.strip(’ ')

135 cms_list.append(line)

136

137returncms_list

138

139

140 # 创建线程

141def****main(url):

142globalCMS

143 url = check_url(url)

144 cms_list = load_cms()

145assertlen(cms_list) > 0

146 work_queue = Queue.Queue()

147

148 # 装载任务

149forpathincms_list:

150 work_queue.put(Cms(url, path))

151 threads = []

152 nloops = range(THREADS)

153

154 # 启动线程

155foriinnloops:

156 t = myThread(work_queue, i)

157 t.start()

158 threads.append(t)

159

160foriinnloops:

161 t.join()

162

163 #return True, CMS

164

165class****Poc:

166def****run(self,target):

167 main(target)

168 cms = CMS

169ifcms == ‘Unknown’:

170returncms,False

171else:

172returncms,True

173

174ifname == ‘main’:

175 cms, is_succes = Poc().run(‘software.hrbeu.edu.cn’)

176print’[!] CMS ==> %s’ % cms

177print’[!] 用时:%f s’ % (time.time()-t)

0x05 总结

以上内容全部由我自己编写爬虫的经验总结而来,如有问题,欢迎指正

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sx77661/article/details/122329629

智能推荐

mac 终端运行 命令 yarn serve报错 /bin/sh: vue-cli-service: command not found 一个命令解决_yarn serve not found_古迪红尘的博客-程序员秘密

mac 终端运行 命令 yarn serve报错 /bin/sh: vue-cli-service: command not found 一个命令解决当你用一个别人给你的vue文件时,无法 在终端中yarn serve 启动服务,报错/bin/sh: vue-cli-service: command not found如下图而你应经安装过了vue/cli 还是这样报错 ,可以输入命令 yarn这个命令是 安装项目的全部依赖...

BING搜索引擎技巧_bing搜索技巧_PanYunXing130的博客-程序员秘密

1.在B类中搜A,A且B格式为:A+B例如搜索引擎中输入”小明+宇航员“,即可出现结果为宇航员2.在非B类中搜索A,A非B格式为:A-B3.指定在某网站搜索A,格式:A site:https://pan.baidu.com/s/在site:后面的网址内搜索A内容4.搜索指定名称或内容的某类型文件,格式:XXXX filetype:ppt、C语言 filetype:pdf...

HBase客户端操作_进入hbase客户端_技术搬砖工的博客-程序员秘密

java类与数据模型Java类型 Hbase数据模型HBaseAdmin 数据库DataBase HBaseConfiguration HTable 表(Table) HTableDescriptor 列族(Column Family) Put Get 列

second order system analysis 自动控制原理 二阶系统的matlab仿真分析_JasonLeaster的博客-程序员秘密

二阶系统的matlab仿真分析二阶系统的matlab仿真分析如上图。根据二阶函数对阶跃函数的响应函数,我们对参数epsilon进行分析讨论可以看出,当epsilon比较小的时候,响应时间短,且伴随有明显的超调。随着epsilon的增大,超调明显降低,epsilon在0.7之后几乎就没有超调了。随着epsilon的增大响应时间变

详解OpenCV的窗口创建函数namedWindow()_昊虹AI笔记的博客-程序员秘密

函数namedWindow()用于创建显示图像的窗口。我们在用窗口显示图像时并不一定要调用这个函数,比如图像显示函数imshow会自动创建图像显示窗口。但有时候我们需要事先对显示图像的窗口对一些设置,就需要用到函数namedWindow()。其C++原型如下:void cv::namedWindow(const String & winname,int flags = WINDOW_AUTOSIZE ) 其Python原型如下:None = cv.namedWindow(winname

随便推点

安卓启动流程_always on processor_lucky tiger的博客-程序员秘密

安卓启动名词缩写笔记:QRD(QualcommReferenceDesign):高通参考设计AOP(Alwaysonprocessor):实时响应处理器SP(SecureProcessor):安全处理器AVB(AndroidVerifiedBoot):安卓开机检验启动SHRM(SystemHardwareResourceManager):系统硬件资源管理器PBL(PrimaryBootLoader):主引导加载程序XBL(eXtensiblebootloader/Secondarybootlo

Github复现之tiramisu(提拉米苏,这里就是FCDenseNet)_如雾如电的博客-程序员秘密

链接:https://github.com/bfortuner/pytorch_tiramisu网络原本是多分类的,而且原始数据输入函数都是为CamVid这样的公开数据集定制的,要用自己的数据还是要花点时间的,我这里是改成了自己的数据输入且为二分类。环境CUDA10.0 CUDNN7.6.0 pytorch1.2.0(环境可以先不改,试试看能不能行,换环境太麻烦),显存12G提示:项目提供的网络有三种复杂度FCDenseNet57、FCDenseNet67、FCDenseNet103,详情见/mode

PCA(一)_pca是线性还是非线性_小麦粒的博客-程序员秘密

1)将原始数据按列组成n行m列矩阵X  2)将X的每一行(代表一个属性字段)进行零均值化,即减去这一行的均值  3)求出协方差矩阵  4)求出协方差矩阵的特征值及对应的特征向量  5)将特征向量按对应特征值大小从上到下按行排列成矩阵,取前k行组成矩阵P  6)Y=PX即为降维到k维后的数据

规范化理论:候选键的求解理论和算法_候选键求解_Shishishi888的博客-程序员秘密

什么是关键码?设关系模式R的属性集是U,X是U的一个子集,F是在R上成立的一个函数依赖集。如果X→U在R上成立(即X→U在中),那么称X是R的一个超键。如果X→U在R上成立,但对X的任一真子集都有→U不成立(即→U不在中,或者XU),那么称X是R上的一个候选键。快速求解候选键的一个充分条件对于给定的关系模式R(, ,…, )和函数依赖集F,可将其属性分为以下四类。...

字节跳动学习笔记:java简历专业技能_菩 提的博客-程序员秘密

第一部分 项目+自我介绍首先上来简单做一下自我介绍?然后让介绍简历里的项目,说下项目里的难点,技术架构。平时开发过程中都遇到过哪些难题?平时都这么和同事沟通?第二部分 java基础方面首先还是老生常谈的hashmap。hashmap的set和get的时间复杂度是多少?为什么是O(1), hashmap 在jdk1.8是线程安全的吗?为什么是线程安全的?concureenthashmap了解吗?他是如何实现线程安全的?说说java泛型,为什么称java泛型为伪泛

推荐文章

热门文章

相关标签