我最近一直在做很多网页解析,我的流程通常看起来像这样:
现在,最简单的答案当然是在下载网页的同时进行抓取,但我不认为这很适合模块化设计,因为我希望能够发展这个过程再多一点。
让我举几个例子来说明我遇到的问题:对于50k页(行),我有一个6gig的数据库。请记住,我们将整个网页存储在一列中,并从中提取相关数据并将其存储到不同的列中。
在桌面上扔一个索引可能需要7到10分钟,在四核上有6 gig的ram。上帝禁止你搞砸了一些东西,看着mysqld跳到70%cpu和所有你的公羊。这是我有第4步 - 我做的每一个操作我都会在我做之前在列上抛出一个索引 - 所以如果我想抓取metas我会抛出一个索引来说明标题列然后更新每个标题不为空的行。
我应该声明我不会一次性完成所有行 - 这往往会让我感到非常糟糕 - 因为它应该 - 你正在将6gig加载到内存中。 ;)
我认为这个问题的解决方案是 - 抓取总计数,然后一次迭代100左右的偏移。
仍然 - 我认为这里也存在一些存储问题。我应该将原始网页存储在文件系统上吗?我曾想过将页面存储到面向文档的数据库中,例如mongo或couch。
修改 这里要明确的是 - 所提出的任何解决方案都应该考虑到50k页面仅由一个用户进行一次批量这一事实。我还没有尝试过多个用户,但我希望能够同时存储多个批次。
答案 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等......