- 浏览: 1654144 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (405)
- C/C++ (16)
- Linux (60)
- Algorithm (41)
- ACM (8)
- Ruby (39)
- Ruby on Rails (6)
- FP (2)
- Java SE (39)
- Java EE (6)
- Spring (11)
- Hibernate (1)
- Struts (1)
- Ajax (5)
- php (2)
- Data/Web Mining (20)
- Search Engine (19)
- NLP (2)
- Machine Learning (23)
- R (0)
- Database (10)
- Data Structure (6)
- Design Pattern (16)
- Hadoop (2)
- Browser (0)
- Firefox plugin/XPCOM (8)
- Eclise development (5)
- Architecture (1)
- Server (1)
- Cache (6)
- Code Generation (3)
- Open Source Tool (5)
- Develope Tools (5)
- 读书笔记 (7)
- 备忘 (4)
- 情感 (4)
- Others (20)
- python (0)
最新评论
-
532870393:
请问下,这本书是基于Hadoop1还是Hadoop2?
Hadoop in Action简单笔记(一) -
dongbiying:
不懂呀。。
十大常用数据结构 -
bing_it:
...
使用Spring MVC HandlerExceptionResolver处理异常 -
一别梦心:
按照上面的执行,文件确实是更新了,但是还是找不到kernel, ...
virtualbox 4.08安装虚机Ubuntu11.04增强功能失败解决方法 -
dsjt:
楼主spring 什么版本,我的3.1 ,xml中配置 < ...
使用Spring MVC HandlerExceptionResolver处理异常
转载请标明出处:http://fuliang.iteye.com/blog/1122051
公司的蜘蛛抓取的内容一个记录是以TAB分割的各个字段的值,并且随着各种分类得分、正文静态得分策略的添加,版本不断的演变。每次做抽样、分析、分类语料等文本处理都需要写一些样板式的代码,并且得到wiki查找指定版本每个字段的位置。构建一个好的DSL来自动处理这件事情能够省去很多重复的操作,只需要关注要处理的事情即可。
我们想提供简单自然的API来做事情,我们常用的需求有:
1、每次版本变更几乎不需要修改代码、只需要添加配置文件,比如新版本增加一个
travel_confidence,我们不需要修改代码就可以使用:
2、可以自动的识别版本、并得到版本号:
3、按照次序给出各个字段的名字:
4、支持模糊查询字段的名字:
5、根据某个字段的模糊或者精确的值来在一个文件中查找记录
6、数字的字段我们需要支持根据大小关系来查找记录:比如gt(>)、ge(>=)
eq(=)、le(<=)、lt(<)
7、比较复杂的需求,我们可以写一些字段小过滤器,来找到需要的记录:
8.我们需要代码DRY。
我们下面看看如何完成这个功能,首先我们可以使用yaml来配置版本以及记录对应的字段:
以及是各个版本是数字字段的版本集合:
功能一:根据字段数来简单识别版本:
我们通过yaml来load版本配置:
我们根据配置文件动态的定义记录的字段,这样我们修改字段,不需要修改代码:
我们写一个CrawlerFile类来支持上面描述的一些功能:
在这个类中定义数字字段支持的关系操作符:
字段和版本的读取方法:
定义初始化方法:
实现define_help_method
支持字段的组合的查询:
关闭文件:
公司的蜘蛛抓取的内容一个记录是以TAB分割的各个字段的值,并且随着各种分类得分、正文静态得分策略的添加,版本不断的演变。每次做抽样、分析、分类语料等文本处理都需要写一些样板式的代码,并且得到wiki查找指定版本每个字段的位置。构建一个好的DSL来自动处理这件事情能够省去很多重复的操作,只需要关注要处理的事情即可。
我们想提供简单自然的API来做事情,我们常用的需求有:
1、每次版本变更几乎不需要修改代码、只需要添加配置文件,比如新版本增加一个
travel_confidence,我们不需要修改代码就可以使用:
crawler_file.find_by_travel_confidence(90) crawler_file.find_by_travel_confidence_gt(50) ...
2、可以自动的识别版本、并得到版本号:
crawler_file.version
3、按照次序给出各个字段的名字:
crawler_file.field_names
4、支持模糊查询字段的名字:
crawler_file.grep_fields(/url/)
5、根据某个字段的模糊或者精确的值来在一个文件中查找记录
#根据host来查找记录 crawler_file.find_by_host("www.9tour.cn") do |record| printf("%s\t%s\n", record.title, record.host) end #根据标题的字段来模糊查找 crawler_file.find_by_title_like(/线路/) do |record| puts record.title end
6、数字的字段我们需要支持根据大小关系来查找记录:比如gt(>)、ge(>=)
eq(=)、le(<=)、lt(<)
#content_confidence大于50的记录 crawler_file.find_by_content_confidence_gt(50) do |record| printf("%s\t%s\n", record.title, record.content_confidence) end
7、比较复杂的需求,我们可以写一些字段小过滤器,来找到需要的记录:
filter = lambda{|host,title| host == "www.9tour.cn" && title =~ /线路/} crawler_file.find_by_fields([:host,:title],filter) do |record| printf("%s\t%s\n", record.host,record.title) end
8.我们需要代码DRY。
我们下面看看如何完成这个功能,首先我们可以使用yaml来配置版本以及记录对应的字段:
v1: download_time: 0 host: 1 url: 2 url_md5: 3 parent_url_md5: 4 crawl_level: 5 loading_time: 6 anchor_text: 7 title: -4 keywords: -3 description: -2 content: -1 v2: download_time: 0 host: 1 url: 2 url_md5: 3 parent_url_md5: 4 crawl_level: 5 loading_time: 6 http_code: 7 content_confidence: 8 anchor_text: 9 title: -4 keywords: -3 description: -2 content: -1 ...#中间省略 v9: download_time: 0 host: 1 url: 2 url_md5: 3 parent_url_md5: 4 crawl_level: 5 publish_time: 6 http_code: 7 content_confidence: 8 list_confidence: 9 feeling_confidence: 10 travel_confidence: 11 qnc_cat: 12 qnc_chi: 13 qnc_zhu: 14 qnc_xing: 15 qnc_you: 16 qnc_gou: 17 qnc_le: 18 anchor_text: 19 raw_title: -10 title: -9 keywords: -8 description: -7 content: -6 lda_tag: -5 location_text: -4 location_confidence: -3 hotel_confidence: -2 gonglue_confidence: -1
以及是各个版本是数字字段的版本集合:
num_fields: - download_time - crawl_level - publish_time - content_confidence - list_confidence - feeling_confidence - travel_confidence - hotel_confidence - gonglue_confidence
功能一:根据字段数来简单识别版本:
class VersionDetector @@field_num_version_map = { 12 => 1, 14 => 2, 15 => 3, 24 => 4, 25 => 5, 16 => 6, 26 => 7, 27 => 8, 30 => 9 }; class << self def detect(file) version = -1 if file.is_a?(String) then line = File.open(file) do |file| file.gets end version = @@field_num_version_map[line.split(/\t/).size] elsif file.is_a?(File) then before_pos = file.pos file.seek(0) line = file.gets version = @@field_num_version_map[line.split(/\t/).size] file.seek(before_pos) else raise ArgumentError.new 'Argument type: #{file.class} is error, must be a String or File type' end raise Exception.new 'Unkown version file format' if version.nil? return version end end end
我们通过yaml来load版本配置:
require 'yaml' class FieldConfig attr_reader :fields_map, :num_fields def initialize(version) config = YAML.load_file 'conf.yml' @fields_map = config["v#{version}"] @num_fields = config["num_fields"] end end
我们根据配置文件动态的定义记录的字段,这样我们修改字段,不需要修改代码:
class CrawlerRecord def self.config(field_config) @@field_config = field_config attr_reader *(field_config.fields_map.keys) #动态定义字段的读方法 end def initialize(raw_line) @raw_line = raw_line fields = raw_line.split(/\t/) @@field_config.fields_map.each do |key,value|#动态设置各个字段的值 instance_variable_set("@" + key.to_s,fields[value]) end end def raw @raw_line end end
我们写一个CrawlerFile类来支持上面描述的一些功能:
class CrawlerFile end
在这个类中定义数字字段支持的关系操作符:
@@num_fields_op = { :gt => ">", :lt => "<", :eq => "=", :ge => ">=", :le => "<=" };
字段和版本的读取方法:
attr_reader :field_names, :version
定义初始化方法:
def initialize(path) @file = File.new(path) #对应的文件 @version = VersionDetector.detect(@file) #得到版本信息 @@field_config = FieldConfig.new(@version) #得到该版本的配置 @field_names = @@field_config.fields_map.keys #根据配置文件得到字段名字 CrawlerRecord.config(@@field_config) #配置CrawlerRecord动态生成字段读方法 define_help_method #定义帮助方法,来完成上面列举的其他功能 end
实现define_help_method
def define_help_method CrawlerFile.class_eval do #根据配置文件动态定义按照一个字段模糊查找方法find_by_xxx_like @@field_config.fields_map.keys.each do |field| define_method :"find_by_#{field}_like" do |regex,&block| if block.nil? then lines = [] @file.each_line do |raw_line| line = CrawlerRecord.new(raw_line) lines << line if line.send(field) =~ regex end lines else @file.each_line do |raw_line| line = CrawlerRecord.new(raw_line) block.call(line) if line.send(field) =~ regex end end @file.seek(0) end #根据配置文件动态定义按照一个字段模糊查找方法find_by_xxx define_method :"find_by_#{field}" do |value,&block| if block.nil? then lines = [] @file.each_line do |raw_line| line = CrawlerRecord.new(raw_line) lines << line if line.send(field) == value end lines else @file.each_line do |raw_line| line = CrawlerRecord.new(raw_line) block.call(line) if line.send(field) == value end end @file.seek(0) end end #为所有的数字字段动态定义按照大小关系查找的方法: @@field_config.num_fields.each do |field| next if not @@field_config.fields_map[field] @@num_fields_op.keys.each do |op| define_method :"find_by_#{field}_#{op.to_s}" do |value,&block| op_val = @@num_fields_op[op] if block.nil? then lines = [] @file.each_line do |raw_line| line = CrawlerRecord.new(raw_line) field_val = line.send(field) lines << line if eval("#{field_val} #{op_val} #{value}") end lines else @file.each_line do |raw_line| line = CrawlerRecord.new(raw_line) field_val = line.send(field) block.call(line) if eval("#{field_val.to_i} #{op_val} #{value}") end end @file.seek(0) end end end end end
支持字段的组合的查询:
def find_by_fields(fields,cond_checker) if block_given? then @file.each_line do |raw_line| line = CrawlerRecord.new(raw_line) yield line if cond_checker.call(*fields.collect{|field| line.send(field) }) end else lines = [] @file.each_line do |line| line = CrawlerRecord.new(raw_line) lines << line if cond_checker.call(*fields.collect{|field| line.send(field)}) end lines end @file.seek(0) end
关闭文件:
def close @file.close end
发表评论
-
[zz]推荐系统-从入门到精通
2013-04-20 14:38 2494为了方便大家从理论到实践,从入门到精通,循序渐进系统地理解和掌 ... -
机器学习在公司的分享
2013-02-23 12:38 2909机器学习在公司的分享,ppt见附件,主要简单介绍了机器学习: ... -
Deep learning的一些教程[rz]
2013-02-03 19:14 27122转载自http://baojie.o ... -
[ZZ]计算机视觉、模式识别、机器学习常用牛人主页链接
2012-11-30 13:13 12213牛人主页(主页有很多论文代码) Serge ... -
Deep learning的一些有用链接
2012-11-12 19:09 3496deeplearning tutorials: http:// ... -
信息论学习总结(二)最大熵模型
2012-06-04 08:13 0显然,如果A表示可能的类别,B表示可能的上下文,p应该最大化熵 ... -
信息论学习总结(一)基础知识
2012-06-02 22:57 4413我们考虑一下一个离散的随机变量x,当我们观察到它的一个值,能给 ... -
loss function
2012-05-11 22:54 2601几种损失函数: 对于回归问题: 平方损失: 绝对值损失: −i ... -
Large-Scale Support Vector Machines: Algorithms and Theory
2012-04-12 00:32 0支持向量机是一种流行 ... -
使用SGD(Stochastic Gradient Descent)进行大规模机器学习
2012-05-11 23:01 44127使用SGD(Stocha ... -
松本行弘的程序世界
2011-10-02 16:49 1395全书涉及到程序设计的方方面面,买这边书的目的希望能看到看看Ru ... -
Ruby HTTP/HTML parser相关资源
2011-09-28 12:04 1840Net::HTTP: http://ruby-doc.org ... -
命令行词典
2011-09-27 14:50 2023经常要查单词,所以利用qq dict api写了一个命令行词典 ... -
构建自己的DSL之三 抓取文件管理
2011-07-18 23:26 1746转载请标明出处:http://fuliang.iteye.co ... -
构建自己的DSL之一 Simple Crawler
2011-07-11 22:08 3012转载请标明出处:http://fuliang.iteye.co ... -
paper and book阅读
2011-06-28 23:19 2646我微博每周读论 ... -
轻松删除所有安装的gem
2011-06-13 12:28 7979删除安装所有的gem: gem list | cut -d ... -
模式识别和机器学习 笔记 第四章 线性分类模型(二)
2011-05-29 23:13 04.3 概率判别模型 对于两类的分类问题,我们已经看到c1的后 ... -
模式识别和机器学习 笔记 第四章 线性分类模型(一)
2011-05-26 23:36 9849转载请标明出处: http:/ ... -
模式识别和机器学习 第六章 核方法
2011-05-11 23:55 0在第3,4章,我们已经考虑了回归和分类的线性参数模型,参数向量 ...
相关推荐
2. **数据处理与存储**:Scrapy可以通过`elasticsearch-dsl`库将抓取的数据直接索引到Elasticsearch。Elasticsearch会自动处理数据,建立倒排索引,以便于快速搜索。此外,Elasticsearch还支持实时数据分析,可以对...
skrape.it虽然主要是为了测试设计,但它的功能同样可以用于构建简单的爬虫,从一个或多个页面中抓取特定的数据。 **Scraper** 是指用于从网页中提取数据的工具。skrape.it提供了这样的工具,它支持解析HTML元素并...
在本篇中,我们将深入探讨如何使用Irony库来创建一个特定于领域的语言(DSL),并结合WinForms构建一个示例应用程序。Irony是一个开源的.NET框架,它为开发人员提供了一种简单的方法来实现词法分析器和语法解析器,...
通过构建表达式树,pyparsing可以轻松解析具有嵌套结构的数据,这在处理命令行参数、配置文件或创建自己的DSL(领域特定语言)时非常有用。 这两个库在许多项目中都有应用,特别是在数据分析、日志分析、自动化脚本...
同时,由于其与Scala的无缝集成,可以方便地与其他强大的Scala库(如Apache Spark、Akka HTTP等)结合,构建复杂的数据处理流水线。 总的来说,Scala-scraper是一个强大且易用的工具,它简化了HTML解析和内容提取的...
此外,我们还将讨论分析器(Analyzer)的设置,它是处理文本的关键组件,负责将文本分词以便于搜索。 查询处理是全文搜索引擎的核心。我们将学习如何使用Elasticsearch的Query DSL(Domain Specific Language)编写...
这个过程通常涉及数据抓取、处理和索引,以便于后续的搜索和分析。 描述中的"ElasticSearch Moviedb"可能是指一个定制的Elasticsearch应用或工具,用于处理电影数据库的数据。提到"在本地ElasticSearch中插入来自...
3. **数据清洗**: 对抓取到的数据进行格式化、去重和异常值处理,确保数据质量。 **三、Elasticsearch数据导入** 将预处理后的数据导入Elasticsearch,通常通过以下步骤: 1. **安装Elasticsearch**: 在本地或...
《构建统一搜索平台:Java技术为核心的实践指南》 在当今数据爆炸的时代,高效、精准的搜索功能已经成为各类应用不可或缺的一部分。"search-platform:统一搜索平台"项目正致力于解决这一问题,它采用Java技术栈,...