2010-03-24 56 views
1

我打算开发一个使用java的网络爬虫来从酒店网站获取酒店房间价格。
在这种情况下,我想用房间类型和用餐类型来捕获房间价格,所以我的算法应该是聪明的来处理。捕获特定字符串的模糊实现

例如:

Room type: Deluxe 
Meal type: HalfBoad 
price : $20.00 

的主要问题是房企可以在不同的酒店网站不同的方式。所以我的算法应该独立于酒店网站。

我打算使用以上房间类型和膳食类型作为模糊集,并使用合适的隶属函数将网页中的词与上述模糊集进行比较。

任何有经验的人?或对我的问题有想法?

回答

3

有两种方法可以解决这个问题:

  1. 您可以自定义履带了解不同的网站使用的格式;或

  2. 您可以想出一个通用(“模糊”)解决方案。

(1)到目前为止是最容易的。理想情况下,您希望创建一些工具使其更容易,以便您可以在最短的时间内为任何新站点创建过滤器。恕我直言,你的时间将最好用在这种方法上。 (2)有很多问题。首先它是不可靠的。你会遇到你不明白或者(更糟糕)出错的格式。其次,它需要大量的开发工作。这是您在处理数千或数百万个网站时使用的类型。

有了数百个网站,您将获得更好和更可预测的结果(1)。

+0

+1肯定 - (1)是要走的路(2)是死亡。 – 2010-03-24 01:02:54

+0

嘿cletus,tnx for ur attention frist, 我也同意你的第一选择,但这是我在大学的最后一年的项目,他们问我一个通用的解决方案,因为你在选项2中提到。 我仍然是最后一年在此之前,研究生并没有遇到过这类问题。 你有任何经验的选项2. 任何方式tnx你的注意agin :) – 2010-03-24 09:19:25

+0

@Kasun:这就是为什么人们离开大学时认为他们已经学会了如何编写软件,并破碎找出计算机科学和软件开发几乎都是无关紧要的。这将是一项艰巨的任务。在现实世界中,你可以更好地展示利用人类智能的成本远远低于创造机器智能。没有理由在学术界也不这样做。 – 2010-03-24 15:09:59

0

与所有问题一样,设计可以让您的价值适应您没有比通常解决方案更快考虑的情况。

首先写一些解析来自一个提供者的数据 - 最简单的格式来处理数据。找到一种方法将该处理程序调整为您的爬虫。一定要封装建设 - 你应该总是这样做反正...

public class RoomTypeExtractor 
{ 
    private RoomTypeExtractor() { } 

    public static RoomTypeExtractor GetInstance() 
    { 
    return new RoomTypeExtractor(); 
    } 

    public string GetRoomType(string content) 
    { 
    // BEHAVIOR #1 
    } 
} 

GetInstance(),ethod让你提升到一个战略模式的几乎免费。

然后添加你的第二个提供者类型。举个例子,比如,你有一个比第一种格式更普遍一些的稍微复杂的数据格式。通过重构什么是你的具体房型提取类与它背后的一个变化的抽象启动,并有GetInstance()方法返回的具体类型的实例:

public abstract class RoomTypeExtractor 
{ 
    public static RoomTypeExtractor GetInstance() 
    { 
    return SimpleRoomTypeExtractor.GetInstance(); 
    } 

    public abstract string GetRoomType(string content); 
} 

public final class SimpleRoomTypeExtractor extends RoomTypeExtractor 
{ 
    private SimpleRoomTypeExtractor() { } 

    public static SimpleRoomTypeExtractor GetInstance() 
    { 
    return new SimpleRoomTypeExtractor(); 
    } 

    public string GetRoomType(string content) 
    { 
    // BEHAVIOR #1 
    } 
} 

创建一个实现了空对象模式的另一个变化。 ..

public class NullRoomTypeExtractor extends RoomTypeExtractor 
{ 
    private NullRoomTypeExtractor() { } 

    public static NullRoomTypeExtractor GetInstance() 
    { 
    return new NullRoomTypeExtractor(); 
    } 

    public string GetRoomType(string content) 
    { 
    // whatever "no content" behavior you want... I chose returning null 
    return null; 
    } 
} 

添加一个基类,将使其更容易与责任链模式就是在这个问题上的工作:

public abstract class ChainLinkRoomTypeExtractor extends RoomTypeExtractor 
{ 
    private final RoomTypeExtractor next_; 

    protected ChainLinkRoomTypeExtractor(RoomTypeExtractor next) 
    { 
    next_ = next; 
    } 

    public final string GetRoomType(string content) 
    { 
    if (CanHandleContent(content)) 
    { 
     return GetRoomTypeFromUnderstoodFormat(content); 
    } 
    else 
    { 
     return next_.GetRoomType(content); 
    } 
    } 

    protected abstract bool CanHandleContent(string content); 
    protected abstract string GetRoomTypeFromUnderstoodFormat(string content); 
} 

现在,重构原有的实施有加入一个基类成责任链管理

public final class SimpleRoomTypeExtractor extends ChainLinkRoomTypeExtractor 
{ 
    private SimpleRoomTypeExtractor(RoomTypeExtractor next) 
    { 
    super(next); 
    } 

    public static SimpleRoomTypeExtractor GetInstance(RoomTypeExtractor next) 
    { 
    return new SimpleRoomTypeExtractor(next); 
    } 

    protected string CanHandleContent(string content) 
    { 
    // return whether or not content contains the right format 
    } 

    protected string GetRoomTypeFromUnderstoodFormat(string content) 
    { 
    // BEHAVIOR #1 
    } 
} 

一定要更新RoomTypeExtractor.GetInstance()

public static RoomTypeExtractor GetInstance() 
    { 
    RoomTypeExtractor extractor = NullRoomTypeExtractor.GetInstance(); 

    extractor = SimpleRoomTypeExtractor.GetInstance(extractor); 

    return extractor; 
    } 

一旦这样做了,创建的责任链一个新的链接...

public final class MoreComplexRoomTypeExtractor extends ChainLinkRoomTypeExtractor 
{ 
    private MoreComplexRoomTypeExtractor(RoomTypeExtractor next) 
    { 
    super(next); 
    } 

    public static MoreComplexRoomTypeExtractor GetInstance(RoomTypeExtractor next) 
    { 
    return new MoreComplexRoomTypeExtractor(next); 
    } 

    protected string CanHandleContent(string content) 
    { 
    // Check for presence of format #2 
    } 

    protected string GetRoomTypeFromUnderstoodFormat(string content) 
    { 
    // BEHAVIOR #2 
    } 
} 

最后,添加新的链接链,如果这是一种较为常见的格式,你可能想给它更高的优先级,将其置于较高的链(支配链的顺序,真正的力量,当你做到这一点显而易见):

public static RoomTypeExtractor GetInstance() 
    { 
    RoomTypeExtractor extractor = NullRoomTypeExtractor.GetInstance(); 

    extractor = SimpleRoomTypeExtractor.GetInstance(extractor); 
    extractor = MoreComplexRoomTypeExtractor.GetInstance(extractor); 

    return extractor; 
    } 

随着时间的推移,你可能要添加的方式来动态如Cletus所指出的那样,为责任链增加新的链接这里的基本原理是Emergent Design。从高质量开始。保持高质量。开车测试。做这三样东西,你就可以用你的耳朵之间的模糊逻辑引擎克服几乎任何问题......

编辑

翻译成Java。希望我做对了;我有点生疏。

+0

嗨MaxGuernseyIII,我真的很满意你的代码和你的atemps。真的,它会充分利用我的发展,但在这个时候,我希望帮助识别房间类型和价格的膳食类型, (使用智能算法) 任何wy realy tnx格恩西, – 2010-03-24 09:08:42

+0

@Kasun:代码是为了演示一个不直接使用的过程。在这个时候,参与这种过程 - 让设计出现的过程 - 比试图编写智能算法更有效果。 – 2010-03-24 15:17:01