Python:使用Scrapy脚本 - 这是从论坛中抓取网址的最佳方式吗?

时间:2016-01-24 01:50:28

标签: python web-scraping scrapy

我想做什么:

  • 从此网站抓取所有网址:http://www.captainluffy.net/ (我的朋友网站,我有权从网上抓取网址)
  • 但是,我不能只是粗暴一切,因为我最终会有很多重复的链接(98%是重复的)
  • 即使我让我的日志文件只包含唯一的网址,它仍然可能是几百万个链接(这需要相当长的时间才能获得)。

由于这个原因,我可以暂停/恢复我的碎片脚本: http://doc.scrapy.org/en/latest/topics/jobs.html

我已设置脚本,因此它会分割每1,000,000条记录。
并且Python字典仅检查每个文本文件中的重复项的url键。所以至少,每个文件中的网址都是唯一的。如果我有一个更大的字典。它会极大地减缓IMO的进程。拥有1个重复(每1,000,000个日志)优于数千个。

这是我目前正在使用的Python脚本代码:

from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.linkextractors.lxmlhtml import LxmlLinkExtractor
from scrapy.item import Item, Field

class MyItem(Item):
	url=Field()


f=open("items0"+".txt","w")
num=open("number.txt","w")
class someSpider(CrawlSpider):
  name = "My script"
  domain=raw_input("Enter the domain:\n")
  allowed_domains = [domain]
  starting_url=raw_input("Enter the starting url with protocol:\n")
  start_urls = [starting_url]
  i=0
  j=0
  dic={}
  global f

  rules = (Rule(LxmlLinkExtractor(allow_domains=(domain)), callback='parse_obj', follow=True),)


  def parse_obj(self,response):
    for link in LxmlLinkExtractor(allow_domains=(self.domain)).extract_links(response):
        item = MyItem()
        item['url'] = link.url
        if self.dic.has_key(item['url']):
          continue
        global f
        global num
        f.write(item['url']+"\n")
        self.dic[item['url']]=True
        self.i+=1
        if self.i%1000000==0:
          self.j+=1
          f.close()
          f=open("items"+str(self.j)+".txt","w")
          num.write(str(self.j+1)+"\n")

有人有更好的刮刮方法吗?
您估计我的scrapy脚本会从这样的网站中获取多少个日志文件?

1 个答案:

答案 0 :(得分:1)

DUPEFILTER_CLASS的Scrapy删除重复请求,默认设置为RFPDupeFilter,与您的方法类似,但不会将看到的网址保存到许多文件中。

我创建了一个POC。

# -*- coding: utf-8 -*-
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors.lxmlhtml import LxmlLinkExtractor


class ExampleSpider(CrawlSpider):
    name = "ExampleSpider"
    allowed_domains = ["www.example.com", "www.iana.org"]
    start_urls = (
        'http://www.example.com/',
    )
    rules = (Rule(LxmlLinkExtractor(allow_domains=allowed_domains), callback='parse_obj', follow=True),)
    log_file = open('test.log', 'a')

    def parse_obj(self, response):
        #self.logger.info(response.url)
        self.logger.info(self.settings['DUPEFILTER_CLASS'])
        self.log_file.write(response.url + '\n')

使用scrapy crawl ExampleSpider -s DUPEFILTER_DEBUG=1运行它,应该有一些调试信息如下。

  

[scrapy] DEBUG:已过滤的重复请求:< GET http://www.iana.org/about/framework>