发起一个开源项目http://www.abelkhan.com/

目前而言,已经用python编写了一个网络爬虫抓取页面,和一个简单的前端

网络爬虫,已经有很多高手写过,我基本上奉行了拿来主义,

得益于python完善的lib,这个网络爬虫实现起来非常的简单:

使用urllib2从对应的url地址抓取html

  1. def get_page(url):
  2. try:
  3. headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebkit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240',
  4. 'Connection':'Keep-Alive',
  5. 'Accept':'text/html, application/xhtml+xml, image/jxr, */*',
  6. 'Accept-Language':'zh-Hans-CN,zh-Hans;q=0.8,en-US;q=0.5,en;q=0.3',
  7. }
  8.  
  9. cookie_jar = cookielib.CookieJar()
  10. opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie_jar))
  11. req = urllib2.Request(url = url, headers = headers)
  12. response = opener.open(req, timeout = 5)
  13. the_page = response.read()
  14. headers = response.info()
  15.  
  16. return the_page, headers
  17. except:
  18. import traceback
  19. traceback.print_exc()

一个需要注意的地方是,有部分网站会限制爬虫访问,所以我加入了headers用于模拟浏览器访问。

这个方法差强人意,但是我也没有找到一个更完善的办法。

抓取到页面后,基于HTMLParser做了html的解析:

  1. class htmlprocess(HTMLParser.HTMLParser):
  2. def __init__(self, urlinfo):
  3. HTMLParser.HTMLParser.__init__(self)
  4.  
  5. self.urllist = {}
  6. self.sub_url = ""
  7.  
  8. self.urlinfo = urlinfo
  9. self.current_url = urlinfo['url']
  10.  
  11. keywords = doclex.simplesplit(self.current_url)
  12. for key in keywords:
  13. if key != "com" and key != "www" and key != "cn":
  14. self.urlinfo['keys'][''].append(key)
  15.  
  16. self.current_tag = ""
  17. self.style = ""
  18.  
  19. def handle_starttag(self, tag, attrs):
  20. self.current_tag = tag
  21. self.style = 'None'
  22. self.sub_url = ""
  23.  
  24. if tag == 'meta':
  25. for name,value in attrs:
  26. if name == 'name':
  27. if value == 'keywords' or value == 'metaKeywords':
  28. self.style = 'keywords'
  29. elif value == 'description' or value == 'metaDescription':
  30. self.style = 'profile'
  31.  
  32. for name,value in attrs:
  33. if name == 'content':
  34. if self.style == 'keywords':
  35. keywords = doclex.simplesplit(value)
  36. if isinstance(keywords, list):
  37. for key in keywords:
  38. self.urlinfo['keys'][''].append(key)
  39. elif self.style == 'profile':
  40. self.urlinfo['profile'][''] = value
  41.  
  42. encodingdate = chardet.detect(value)
  43. if encodingdate['encoding']:
  44. udata = unicode(value, encodingdate['encoding'])
  45. tlen = 16
  46. if len(udata) < 16:
  47. tlen = len(udata)
  48. self.urlinfo['titlegen'].append(udata[0:tlen].encode('utf-8'))
  49. else:
  50. self.urlinfo['titlegen'].append(value)
  51.  
  52. if tag == 'a' or tag == 'A' or tag == 'link':
  53. self.sub_url = ""
  54. for name,value in attrs:
  55. if name == 'href':
  56. if len(value) == 0:
  57. return
  58.  
  59. if not judged_url(value):
  60. if self.current_url[len(self.current_url) - 1] != '/' and value[0] != '/':
  61. value = self.current_url + '/' + value
  62. else:
  63. value = self.current_url + value
  64.  
  65. if value.find('javascript') != -1:
  66. return
  67.  
  68. if value.find('javaScript') != -1:
  69. return
  70.  
  71. if self.current_url.find("apple") != -1:
  72. if value.find("http://www.apple.com/cn/mac#ac-gn-menustate") !=-1:
  73. return
  74.  
  75. if self.current_url.find("cnblogs") != -1:
  76. if value.find("http://msg.cnblogs.com/send?recipient=itwriter") != -1:
  77. return
  78. elif value.find("http://i.cnblogs.com/EditPosts.aspx?opt=1") != -1:
  79. return
  80. elif value.find("http://i.cnblogs.com/EditPosts.aspx?postid=1935371") != -1:
  81. return
  82. elif value.find("http://msg.cnblogs.com/send?recipient=itwriter/") != -1:
  83. return
  84. elif value.find("http://msg.cnblogs.com/send?recipient=itwriter/GetUsername.aspx") != -1:
  85. return
  86. elif value.find("/EnterMyBlog.aspx?NewArticle=1") != -1:
  87. return
  88. elif value.find("GetUsername") != -1:
  89. return
  90. elif value.find("GetMyPassword") != -1:
  91. return
  92. elif value.find("http://i.cnblogs.com/EditPosts.aspx?postid=") != -1:
  93. return
  94. elif value[len(value) - 1] == '#':
  95. value = value[0:-1]
  96.  
  97. if self.current_url.find(value) != -1:
  98. return
  99.  
  100. if value[len(value) - 1] == '#':
  101. value = value[0:-1]
  102.  
  103. if value != self.current_url and len(value) < 64 and not ingoreurl(value):
  104. self.urllist[value] = {'url':value, 'keys':{'':[], '':[], '':[]}, 'title':'', 'titlegen':[], 'profile':{'':'', '':'', '':[]}}
  105. self.sub_url = value
  106. print value
  107.  
  108. def handle_data(self, data):
  109. if self.current_tag == 'title':
  110. try:
  111. data = doclex.delspace(data)
  112. keys = doclex.lex(data)
  113. if isinstance(keys, list) and len(keys) > 0:
  114. for key in keys:
  115. self.urlinfo['keys'][''].append(key)
  116. if len(data) > 0:
  117. self.urlinfo['title'] = data
  118. except:
  119. import traceback
  120. traceback.print_exc()
  121.  
  122. elif self.current_tag == 'a':
  123. try:
  124. if self.sub_url != "":
  125. keys = doclex.simplesplit(data)
  126. if isinstance(keys, list) and len(keys) > 0:
  127. for key in keys:
  128. if key in self.urllist[self.sub_url]['keys']['']:
  129. self.urllist[self.sub_url]['keys'][''].remove(key)
  130. if key not in self.urllist[self.sub_url]['keys'][''] and key not in self.urllist[self.sub_url]['keys']['']:
  131. self.urllist[self.sub_url]['keys'][''].append(key)
  132.  
  133. encodingdate = chardet.detect(data)
  134. if encodingdate['encoding']:
  135. udata = unicode(data, encodingdate['encoding'])
  136. tlen = 16
  137. if len(udata) < 16:
  138. tlen = len(udata)
  139. self.urllist[self.sub_url]['titlegen'].append(udata[0:tlen].encode('utf-8'))
  140. if len(udata) > 16:
  141. self.urllist[self.sub_url]['profile'][''] = udata[0:32].encode('utf-8')
  142.  
  143. except:
  144. import traceback
  145. traceback.print_exc()
  146. else:
  147. try:
  148. if not doclex.invialddata(data):
  149. data = doclex.delspace(data)
  150.  
  151. encodingdate = chardet.detect(data)
  152. udata = unicode(data, encodingdate['encoding'])
  153. tlen = 16
  154. if len(udata) < 16:
  155. tlen = len(udata)
  156. self.urlinfo['titlegen'].append(udata[0:tlen].encode('utf-8'))
  157.  
  158. if len(udata) > 32:
  159. self.urlinfo['profile'][''].append((udata[0:32] + u"...").encode('utf-8'))
  160.  
  161. keys1 = doclex.lex(data)
  162. for key in keys1:
  163. self.urlinfo['keys'][''].append(key)
  164.  
  165. except:
  166. import traceback
  167. traceback.print_exc()

基本上,要说的就是HTMLParser使用方法见文档,HTMLParser预先了定义了一组虚接口handle_starttag,handle_data和handle_endtag,使用者通过重载这三个接口,来实现对html中的tag进行处理,进而完整的解析抓取到的html。

然后从搜索结果来看,搜索的质量还很不尽如人意,欢迎大家的参与和提出意见

项目地址:http://www.abelkhan.com/

向我们提出意见:http://www.abelkhan.com/guestbook/

对项目进行捐助:http://www.abelkhan.com/collection/

代码托管地址如下:https://github.com/qianqians/websearch欢迎大家参与

开源搜索引擎abelkhan的更多相关文章

  1. 开源搜索引擎Iveely 0.8.0发布,终见天日

    这是一篇博客,不是,这是一篇开源人的心酸和喜悦,没有人可以理解我们的心情,一路的辛酸一路的艰辛,不过还好,在大家的支持下,总算是终见天日,谢谢那些给予我们无私帮助的朋友.您的支持,依然是我们无限的动力 ...

  2. 开源搜索引擎Iveely 0.7.0发布,不一样,那就让他不一样!

    2012年08月05日,Iveely Search Engine 0.1.0发布,今天,怀着对于未来的追求,终于,0.7.0如期和大家见面了,7个版本,历时2年4个月,感谢大家的支持,感谢我不离不弃的 ...

  3. 开源搜索引擎评估:lucene sphinx elasticsearch

    开源搜索引擎评估:lucene sphinx elasticsearch 开源搜索引擎程序有3大类 lucene系,java开发,包括solr和elasticsearch sphinx,c++开发,简 ...

  4. 开源搜索引擎Iveely 0.8.0

    开源搜索引擎Iveely 0.8.0 这是一篇博客,不是,这是一篇开源人的心酸和喜悦,没有人可以理解我们的心情,一路的辛酸一路的艰辛,不过还好,在大家的支持下,总算是终见天日,谢谢那些给予我们无私帮助 ...

  5. Solr vs. Elasticsearch谁是开源搜索引擎王者

    当前是云计算和数据快速增长的时代,今天的应用程序正以PB级和ZB级的速度生产数据,但人们依然在不停的追求更高更快的性能需求.随着数据的堆积,如何快速有效的搜索这些数据,成为对后端服务的挑战.本文,我们 ...

  6. 开源搜索引擎评估:lucene sphinx elasticsearch (zhuan)

    http://lutaf.com/158.htm ************************ 开源搜索引擎程序有3大类 lucene系,java开发,包括solr和elasticsearch s ...

  7. 一些开源搜索引擎实现——倒排使用原始文件,列存储Hbase,KV store如levelDB、mongoDB、redis,以及SQL的,如sqlite或者xxSQL

    本文说明:除开ES,Solr,sphinx系列的其他开源搜索引擎汇总于此.   A search engine based on Node.js and LevelDB A persistent, n ...

  8. 转 Solr vs. Elasticsearch谁是开源搜索引擎王者

    转 https://www.cnblogs.com/xiaoqi/p/6545314.html Solr vs. Elasticsearch谁是开源搜索引擎王者 当前是云计算和数据快速增长的时代,今天 ...

  9. 开源搜索引擎排名第一,Elasticsearch是如何做到的?

    一.引言 随着移动互联网.物联网.云计算等信息技术蓬勃发展,数据量呈爆炸式增长.如今我们可以轻易得从海量数据里找到想要的信息,离不开搜索引擎技术的帮助. ​ 作为开源搜索引擎领域排名第一的 Elast ...

随机推荐

  1. Android 真机无线调试

    有很多人在学Android的时候最开始接触的都是模拟机的测试,如果像好的模拟机比如genimotion,次一点的蓝手指,测试都还比较可以.有的也不缺乏是用真机测试.本人开始用华为真机测试,也是一直连线 ...

  2. How to change current process to background process

    Situation: there is a script or command is running, but we need to close current box/windows to do o ...

  3. Adobe Fireworks CS6 Mac破解版

    Mac下一款快速建站的软件--Adobe Fireworks CS6,小子这里有时间就分享出来给更多需要的朋友. Adobe Fireworks CS6能让您在弹指间创作精美的网站和移动应用程序设计, ...

  4. Ubuntu怎样进行自由截图操作

    全屏截图 1. 很简单,键盘上右上角都有一个 Print Screen按键,敲一下,全屏截图操作完成. 自由截图 1. 此种方式很简单,打开系统设置->键盘,进入shortcuts选项 2. 点 ...

  5. 开涛spring3(6.5) - AOP 之 6.5 AspectJ切入点语法详解

    6.5.1  Spring AOP支持的AspectJ切入点指示符 切入点指示符用来指示切入点表达式目的,,在Spring AOP中目前只有执行方法这一个连接点,Spring AOP支持的Aspect ...

  6. Dubbo微容器(Cooma)详解

    ExtensionLoader ExtensionLoader是Dubbo中的SPI的实现方法,它是Dubbo框架的微容器,也为框架提供各种组件的扩展点 三种注解 SPI Adaptive Activ ...

  7. Nagios配置安装详解

    nagios.html :first-child{margin-top:0!important}img.plugin{box-shadow:0 1px 3px rgba(0,0,0,.1);borde ...

  8. 2.Node.js access_token的获取、存储及更新

    文章目录:         1.Node.js 接入微信公众平台开发         2.Node.js access_token的获取.存储及更新 一.写在前面的话   上一篇文章中,我们使用 No ...

  9. javaSE_05Java中方法(函数)与重载、递归-练习

    1.使用的递归的方法求5! public class DiGui{ public static void main(String[] args){ //使用的递归的方法求5! System.out.p ...

  10. java(3) if结构

    一.基本if结构 1.流程图 1)输入输出 2)判断和分支 3) 流程线 1.1  简单的if条件判断 if(表达式){             //表达式为true,执行{}中的代码 } 示例1:如 ...