我正在从其他网站抓取数据,我经常处理以下情况:
EntityA
IdEntityB
IdEntityC
EntityB
IdEntityD
IdEntityE
上面提到的每个实体都有自己的页面,我想将它们插入到SQL数据库中。但是,我废弃物品的顺序并不是最佳。到目前为止我的解决方案(没有处理外键或任何类型的映射)已经废弃EntityA
的页面,查找指向其相应EntityB
页面的链接并安排该页面也被刮掉了。同时,所有被抓取的实体在bin中被抛出,然后我将集群插入到数据库中。出于性能原因,我等到我有大约2000个实体被抓取将所有实体推入数据库。天真的方法是只插入每个身份而没有唯一的身份,但这意味着我将不得不使用其他(非数字)低质量信息来引用系统上的每个实体。当我无法将所有实体拼凑在一起时,如何保证数据库中有干净的数据?这是使用Python和Scrapy框架。
答案 0 :(得分:3)
在抓取网站的情况下,通常避免冗余的主要因素是跟踪已经被抓取的网址。在你的mysql中有一个表,你只需要抓取的页面的网址(或网址的md5或sha1哈希)。使用表中的该列创建索引。
在刮取任何页面之前检查mysql表是否已经删除了它。这将是一个选择查询,并不会加载mysql太多。我知道你因为性能问题而以批量方式写入db,但是这个选择不会加载mysql那么多。如果您使用多个线程,只需观察并监视与mysql的连接,并在必要时更改配置。
但更好的方法是使用具有3列结构的表格,如下所示:
id | url | crawled_flag
此处在此表中创建一个带有url
的索引,并使其唯一。所以网址不会多余。首先,当您抓取页面时,请创建该行crawled_flag
的{{1}}。然后解析页面并获取此页面中的所有链接,并将true
作为crawled_flag
插入此表中。如果表中已存在该URL,则插入将失败,因为我们已将false
列设为url
。您的下一次抓取应该是unique
为crawled_flag
的行的网址,此循环将继续。这样可以避免因冗余URL导致的数据冗余。