Scrapy, переходить только по внутренним URL-адресам, но извлекать все найденные ссылки

Я хочу получить все внешние ссылки с данного веб-сайта с помощью Scrapy. Используя следующий код, паук также сканирует внешние ссылки:

from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors import LinkExtractor
from myproject.items import someItem

class someSpider(CrawlSpider):
  name = 'crawltest'
  allowed_domains = ['someurl.com']
  start_urls = ['http://www.someurl.com/']

  rules = (Rule (LinkExtractor(), callback="parse_obj", follow=True),
  )

  def parse_obj(self,response):
    item = someItem()
    item['url'] = response.url
    return item

Что мне не хватает? Разве "allowed_domains" не мешает сканированию внешних ссылок? Если я устанавливаю "allow_domains" для LinkExtractor, он не извлекает внешние ссылки. Просто чтобы уточнить: я хочу сканировать не внутренние ссылки, а извлекать внешние ссылки. Любая помощь приветствуется!


person sboss    schedule 15.01.2015    source источник
comment
Если я включу OffsiteMiddleware, ссылки не сканируются, но и не извлекаются. По крайней мере, тогда я могу видеть отфильтрованный внешний запрос на «www.externaldomain». Неужто я здесь упускаю что-то банальное?   -  person sboss    schedule 15.01.2015
comment
просто чтобы понять: вы хотите иметь список всех внешних ссылок для данного веб-сайта?   -  person aberna    schedule 15.01.2015
comment
Да, это правильно!   -  person sboss    schedule 15.01.2015


Ответы (3)


Вы также можете использовать средство извлечения ссылок, чтобы вытащить все ссылки после анализа каждой страницы.

Средство извлечения ссылок отфильтрует ссылки за вас. В этом примере экстрактор ссылок будет запрещать ссылки в разрешенном домене, поэтому он получает только внешние ссылки.

from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors import LxmlLinkExtractor
from myproject.items import someItem

class someSpider(CrawlSpider):
  name = 'crawltest'
  allowed_domains = ['someurl.com']
  start_urls = ['http://www.someurl.com/']

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


  def parse_obj(self,response):
    for link in LxmlLinkExtractor(allow=(),deny = self.allowed_domains).extract_links(response):
        item = someItem()
        item['url'] = link.url
person 12Ryan12    schedule 16.01.2015

Обновленный код, основанный на ответе 12Ryan12,

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

class MyItem(Item):
    url= Field()


class someSpider(CrawlSpider):
    name = 'crawltest'
    allowed_domains = ['someurl.com']
    start_urls = ['http://www.someurl.com/']
    rules = (Rule(LxmlLinkExtractor(allow=()), callback='parse_obj', follow=True),)

    def parse_obj(self,response):
        item = MyItem()
        item['url'] = []
        for link in LxmlLinkExtractor(allow=(),deny = self.allowed_domains).extract_links(response):
            item['url'].append(link.url)
        return item
person Ohad Zadok    schedule 13.08.2015

Решением было бы использовать функцию process_link в документации SgmlLinkExtractor здесь http://doc.scrapy.org/en/latest/topics/link-extractors.html

class testSpider(CrawlSpider):
    name = "test"
    bot_name = 'test'
    allowed_domains = ["news.google.com"]
    start_urls = ["https://news.google.com/"]
    rules = (
    Rule(SgmlLinkExtractor(allow_domains=()), callback='parse_items',process_links="filter_links",follow= True) ,
     )

    def filter_links(self, links):
        for link in links:
            if self.allowed_domains[0] not in link.url:
                print link.url

        return links

    def parse_items(self, response):
        ### ...
person aberna    schedule 15.01.2015
comment
@sboss Я заметил, что вы приняли мое предложенное решение, а после отказались от него. Код работает нормально, вы заметили какую-либо другую проблему? - person aberna; 19.01.2015
comment
Привет, Аберна, извините за понижение рейтинга. Я нашел ответ 12Ryan12: s более элегантным, поскольку он позволяет мне использовать встроенные дублирующие фильтры и т. Д. Я ценю ответ! - person sboss; 21.01.2015