如何存储整个WebPages以供稍后解析?

时间:2010-07-03 14:35:12

标签: mysql parsing storage screen-scraping

我最近一直在做很多网页解析,我的流程通常看起来像这样:

  1. 获取Parse
  2. 的链接列表
  3. 将列表导入数据库
  4. 下载每个链接的整个网页并存储到mysql
  5. 为每个抓取会话添加索引
  6. 删除相关部分(内容,元数据等)
  7. 步骤4,5 - 冲洗/重复 - 因为通常需要刮擦差异。稍后来自同一页面的内容或修改您的xpath或擦除所述内容或其他内容。
  8. 将刮刮数据库导出到真实数据库并删除网页列并抓取索引
  9. 现在,最简单的答案当然是在下载网页的同时进行抓取,但我不认为这很适合模块化设计,因为我希望能够发展这个过程再多一点。

    让我举几个例子来说明我遇到的问题:对于50k页(行),我有一个6gig的数据库。请记住,我们将整个网页存储在一列中,并从中提取相关数据并将其存储到不同的列中。

    在桌面上扔一个索引可能需要7到10分钟,在四核上有6 gig的ram。上帝禁止你搞砸了一些东西,看着mysqld跳到70%cpu和所有你的公羊。这是我有第4步 - 我做的每一个操作我都会在我做之前在列​​上抛出一个索引 - 所以如果我想抓取metas我会抛出一个索引来说明标题列然后更新每个标题不为空的行。

    我应该声明我不会一次性完成所有行 - 这往往会让我感到非常糟糕 - 因为它应该 - 你正在将6gig加载到内存中。 ;)

    我认为这个问题的解决方案是 - 抓取总计数,然后一次迭代100左右的偏移。

    仍然 - 我认为这里也存在一些存储问题。我应该将原始网页存储在文件系统上吗?我曾想过将页面存储到面向文档的数据库中,例如mongo或couch。

    修改 这里要明确的是 - 所提出的任何解决方案都应该考虑到50k页面仅由一个用户进行一次批量这一事实。我还没有尝试过多个用户,但我希望能够同时存储多个批次。

4 个答案:

答案 0 :(得分:2)

为什么不在插入数据之前将索引添加到表中?这样,在将行添加到表中时构建索引。

答案 1 :(得分:1)

如果您有更多硬件可以解决问题,您可以使用sharding开始在多台服务器上分发数据库。

我还建议您考虑从您正在捕获的网页中删除无用的信息(例如页面结构标记,JavaScript,样式等),并在适当时压缩结果。

答案 2 :(得分:0)

您可以使用现有的web crawler,例如wget或其他许多其中之一。这可以将文件下载到硬盘,然后您可以解析文件,并将相关信息存储在数据库中。

答案 3 :(得分:0)

感谢您帮我解决所有问题!

我将在这里尝试混合方法:

1)将页面下拉到文件系统上的树结构。

2)将内容放入不包含任何完整网页的通用内容表中(这意味着我们的平均63k列现在可能是k的1/10。

详情

1)用于容纳网页的树形结构如下所示:

-- usr_id1k
|   |-- user1
|   |   |-- job1
|   |   |   |-- pg_id1k
|   |   |   |   |-- p1
|   |   |   |   |-- p2
|   |   |   |   `-- p3
|   |   |   |-- pg_id2k
|   |   |   `-- pg_id3k
|   |   |-- job2
|   |   `-- job3
|   |-- user2
|   `-- user3
|-- usr_id2k
`-- usr_id3k

2)不是为每个“作业”创建一个表然后导出它,我们将有几个不同的表 - 主要表是“内容”表。

content_type, Integer # fkey to content_types table
user_id, Integer # fkey to users table
content, Text # actual content, no full webpages

....其他东西,如created_at,updated_at,perms等......