Scrapy - 如何识别已爬取的URL

15 投票
5 回答
10412 浏览
提问于 2025-04-16 05:04

我正在使用scrapy每天抓取一个新闻网站的内容。请问我该如何限制scrapy不去抓取已经抓取过的链接呢?另外,有没有关于SgmlLinkExtractor的清晰文档或示例呢?

5 个回答

1

我觉得jama22的回答有点不够完整。

在这段代码 if self.FILTER_VISITED in x.meta 中,你可以看到需要在你的请求实例中包含FILTER_VISITED,才能让这个请求被忽略。这样做是为了确保你能区分哪些链接是你想要访问和浏览的,哪些链接是你不想再看到的。

1

这很简单。你可以把之前抓取过的网址保存在一个Python字典里。下次你想再抓取这些网址的时候,就先看看这个网址是否在字典里。如果在,就不用再抓取了;如果不在,那就去抓取。

def load_urls(prev_urls):
    prev = dict()
    for url in prev_urls:
        prev[url] = True
    return prev

def fresh_crawl(prev_urls, new_urls):
    for url in new_urls:
        if url not in prev_urls:
            crawl(url)
    return

def main():
    purls = load_urls(prev_urls)
    fresh_crawl(purls, nurls)
    return

上面的代码是在StackOverflow的文本编辑器,也就是浏览器里输入的。可能会有语法错误,你可能还需要做一些修改。不过逻辑是没问题的……

注意:要小心,有些网站的内容会不断变化。所以有时候你可能需要重新抓取某个特定的网页(也就是同一个网址),以获取更新的内容。

15

其实你可以很简单地做到这一点,方法是使用这里的 scrapy 代码片段:http://snipplr.com/view/67018/middleware-to-avoid-revisiting-already-visited-items/

使用这个代码片段时,先把链接里的代码复制到你 scrapy 项目中的某个文件里。然后在你的 settings.py 文件中添加一行代码来引用它:

SPIDER_MIDDLEWARES = { 'project.middlewares.ignore.IgnoreVisitedItems': 560 }

关于你为什么选择这个数字的具体原因,可以在这里了解:http://doc.scrapy.org/en/latest/topics/downloader-middleware.html

最后,你需要修改你的 items.py 文件,让每个项目类都有以下字段:

visit_id = Field()
visit_status = Field()

我想就这些了。下次你运行爬虫时,它应该会自动开始避免访问相同的网站。

祝你好运!

撰写回答