Использование Scrapy для сканирования URL-адресов на веб-странице - PullRequest
1 голос
/ 18 октября 2011

Я использую scrapy для извлечения данных с определенных веб-сайтов. Проблема в том, что мой паук может сканировать только веб-страницу с начальными start_urls, но не может сканировать URL-адреса на веб-странице.Я точно скопировал одного и того же паука:

    from scrapy.spider import BaseSpider
    from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
    from scrapy.selector import HtmlXPathSelector
    from scrapy.http import Request
    from scrapy.utils.response import get_base_url
    from scrapy.utils.url import urljoin_rfc
    from nextlink.items import NextlinkItem

    class Nextlink_Spider(BaseSpider):
        name = "Nextlink"
        allowed_domains = ["Nextlink"]
        start_urls = ["http://www.dmoz.org/Computers/Programming/Languages/Python/Books/"]

    def parse(self, response):
        hxs = HtmlXPathSelector(response)
        sites = hxs.select('//body/div[2]/div[3]/div/ul/li[2]/a/@href')          
        for site in sites:
            relative_url = site.extract()
            url =  self._urljoin(response,relative_url)
            yield Request(url, callback = self.parsetext)

    def parsetext(self, response):
        log = open("log.txt", "a")
        log.write("test if the parsetext is called")
        hxs = HtmlXPathSelector(response)
        items = []
        texts = hxs.select('//div').extract()
        for text in texts:
            item = NextlinkItem()
            item['text'] = text
            items.append(item)
            log = open("log.txt", "a")
            log.write(text)
        return items

    def _urljoin(self, response, url):
        """Helper to convert relative urls to absolute"""
        return urljoin_rfc(response.url, url, response.encoding)

Я использую log.txt, чтобы проверить, вызван ли parsetext. Однако после запуска моего паука в log.txt ничего не появляется.

Ответы [ 3 ]

1 голос
/ 18 октября 2011

См. Здесь:

http://readthedocs.org/docs/scrapy/en/latest/topics/spiders.html?highlight=allowed_domains#scrapy.spider.BaseSpider.allowed_domains

allow_domains

Необязательный список строк, содержащих домены, которые этот паук может сканировать.Запросы для URL-адресов, не принадлежащих доменным именам, указанным в этом списке, не будут выполняться, если включено OffsiteMiddleware.

Таким образом, если вы не активировали OffsiteMiddleware в своих настройках, это неЭто не имеет значения, и вы можете полностью исключить allowed_domains.

Проверьте settings.py, активировано ли OffsiteMiddleware или нет.Его не следует активировать, если вы хотите, чтобы ваш Spider сканировал любой домен.

1 голос
/ 26 сентября 2015

Я думаю, что проблема в том, что вы не сказали Scrapy следовать каждому просканированному URL.Для своего блога я реализовал CrawlSpider, который использует правила на основе LinkExtractor для извлечения всех релевантных ссылок со страниц моего блога:

# -*- coding: utf-8 -*-

'''
*   This program is free software: you can redistribute it and/or modify
*   it under the terms of the GNU General Public License as published by
*   the Free Software Foundation, either version 3 of the License, or
*   (at your option) any later version.
*
*   This program is distributed in the hope that it will be useful,
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*   GNU General Public License for more details.
*
*   You should have received a copy of the GNU General Public License
*   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
*   @author Marcel Lange <info@ask-sheldon.com>
*   @package ScrapyCrawler 
 '''


from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor

import Crawler.settings
from Crawler.items import PageCrawlerItem


class SheldonSpider(CrawlSpider):
    name = Crawler.settings.CRAWLER_NAME
    allowed_domains = Crawler.settings.CRAWLER_DOMAINS
    start_urls = Crawler.settings.CRAWLER_START_URLS
    rules = (
        Rule(
            LinkExtractor(
                allow_domains=Crawler.settings.CRAWLER_DOMAINS,
                allow=Crawler.settings.CRAWLER_ALLOW_REGEX,
                deny=Crawler.settings.CRAWLER_DENY_REGEX,
                restrict_css=Crawler.settings.CSS_SELECTORS,
                canonicalize=True,
                unique=True
            ),
            follow=True,
            callback='parse_item',
            process_links='filter_links'
        ),
    )

    # Filter links with the nofollow attribute
    def filter_links(self, links):
        return_links = list()
        if links:
            for link in links:
                if not link.nofollow:
                    return_links.append(link)
                else:
                    self.logger.debug('Dropped link %s because nofollow attribute was set.' % link.url)
        return return_links

    def parse_item(self, response):
        # self.logger.info('Parsed URL: %s with STATUS %s', response.url, response.status)
        item = PageCrawlerItem()
        item['status'] = response.status
        item['title'] = response.xpath('//title/text()')[0].extract()
        item['url'] = response.url
        item['headers'] = response.headers
        return item

Вкл. https://www.ask -sheldon.com / build-a-website-crawler-using-scrapy-framework / Я подробно описал, как реализовал сканер веб-сайтов для разогрева моего полностраничного кэша Wordpress.

0 голосов
/ 18 октября 2011

Я думаю, это будет строка:

allowed_domains = ["Nextlink"]

Это не домен, подобный domain.tld, поэтому он будет отклонять любые ссылки. Если взять пример из документации : allowed_domains = ["dmoz.org"]

...