Python Scrapy Dictionary проект - PullRequest
1 голос
/ 27 апреля 2020

Можно ли сделать Python Паук Scrapy, который сканирует весь сайт, создает словарь, который содержит каждое слово, используемое на сайте, в одном столбце, а также показывает URL всех экземпляров каждого слова в столбце рядом с этим? Если да, то как?

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

Я уже создал паука (см. Ниже), который составляет список всех URL-адресов и всего простого текста, найденного в каждом URL-адресе, но мои навыки программирования не достаточно хороши, чтобы понять, как продолжить отсюда , заставьте Python перепрыгнуть через уже собранные данные / слова и превратить их в словарь. Заранее спасибо.

import scrapy
from scrapy.loader import ItemLoader
from digital.items import DataItem
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor


class SampleSpider(CrawlSpider):
    name = "spider"
    allowed_domains = ["example.com"]
    start_urls = ["http://www.example.com"]

    rules = (
        Rule(LinkExtractor(deny=('blog', 'catalogsearch', 'review')),
             callback='parse_page', follow=True),
    )

    def parse_page(self, response):
        l = ItemLoader(item=DataItem(), response=response)
        l.add_value('link', response.url)
        l.add_xpath('text', '//*[not(self::script)]/text()')
        return l.load_item()

И мои items.py:

import scrapy
from scrapy.loader.processors import MapCompose, Join
from w3lib.html import remove_tags


def remove_whitespace(value):
    return value.strip()


class DataItem(scrapy.Item):
    link = scrapy.Field()
    text = scrapy.Field(
        input_processor=MapCompose(remove_tags, remove_whitespace),
        output_processor=Join()
    )

Ответы [ 2 ]

0 голосов
/ 28 апреля 2020

Вы можете использовать Item Pipeline для этого:

from collections import defaultdict


class DictionaryPipeline(object):
    def __init__(self, category_count):
        self.dictionary = defaultdict(list)

    def process_item(self, item, spider):
        # get all unique words from text
        unique_words = {word for words in item['text'] for word in words.split()}

        # insert/update dictionary
        url = item['url']
        for word in unique_words:
            self.dictionary[word].append(url)

        return item

Обратите внимание, что это будет занимать много памяти. Вам, вероятно, лучше отделить логи c (как предложил Gallaecio) и использовать что-то вроде map-Reduce (аналогично этому подходу), чтобы получить конечный результат. Вы также можете рассмотреть возможность использования Item Pipeline, но использовать базу данных для сохранения данных вместо сохранения словаря в памяти.

0 голосов
/ 28 апреля 2020

Мой подход состоит в том, чтобы разделить работу на две части: извлечение и последующая обработка.

Вы используете Scrapy для извлечения элементов с двумя полями: word и url. Я бы экспортировал результаты в виде файла JSON Lines.

Затем вы используете обычный скрипт Python, чтобы превратить полученный файл JSON Lines из Scrapy в желаемый результат, удаляя дубликаты и объединяя элементы. на word, объединяя их url.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...