Необходимо вернуть данные метода обратного вызова Scrapy в вызывающую функцию - PullRequest
0 голосов
/ 23 июня 2019

В приведенном ниже коде я пытаюсь собрать идентификаторы электронной почты с веб-сайта.Это может быть на странице контактов или о нас.Из метода разбора я следую за методом extemail для всех этих страниц.С каждой страницы я собрал несколько электронных адресов.Теперь мне нужно распечатать их с оригинальной записью, отправленной в метод init .

Например: record = "https://www.wockenfusscandies.com/"

Я хочу напечатать вывод как, https://www.wockenfusscandies.com/|abc@gamil.com|def@outlook.com

Я не могу сохранить их в self.emails и доставить обратно по методу init .

Пожалуйста, помогите.

import scrapy
from scrapy.crawler import CrawlerProcess


class EmailSpider(scrapy.Spider):

    def __init__(self, record):
        self.record = record
        self.emails = []

        url = record.split("|")[4]

        if not url.startswith("http"):
            url = "http://{}".format(url)

        if url:
            self.start_urls = ["https://www.wockenfusscandies.com/"]
        else:
            self.start_urls = []

    def parse(self, response):
        contact_list = [a.attrib['href'] for a in response.css('a') if 'contact' in a.attrib['href'] or 'about' in a.attrib['href']]
        contact_list.append(response.request.url)

        for fllink in contact_list:
            yield response.follow(fllink, self.extemail)

    def extemail(self, response):
        emails = response.css('body').re('[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+')
        yield {
            'emails': emails
        }

process = CrawlerProcess({
    'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'
})
f = open("/Users/kalpesh/work/data/test.csv")
for rec in f:
    process.crawl(EmailSpider, record=rec)
f.close()
process.start()

Ответы [ 2 ]

0 голосов
/ 24 июня 2019

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

Какой-то псевдокод:

def parse(self, response):
    meta = response.meta
    if not meta.get('seen'):
    # -- finding urls of contact and about us pages --
    # -- putting it to meta['queue'] --
    # -- setting meta['seen'] = True

    page_emails_found = ...getting emails here...
    # --- extending already discovered emails 
    # --- from other pages/initial empty list with new ones
    meta['emails'].extend(page_emails_found)

    # if queue isn't empty - yielding new request
    if meta['queue']:
       next_url = meta['queue'].pop()
       yield Request(next_url, callback=self.parse, meta=copy(meta))
    # if queue is empty - yielding result from meta
    else:
       yield {'url': current_domain, 'emails': meta['emails']}


Как то так ..

0 голосов
/ 24 июня 2019

Если я правильно понимаю ваше намерение, вы можете попробовать следующее:

а) собирать почтовые идентификаторы в self.emails как

def extemail(self, response):
    emails = response.css('body').re('[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+')
    self.emails = emails.copy()
    yield {
        'emails': emails
    }

(или каким другим способом вы получаете адреса электронной почты от emails)

b) добавить метод закрытия (self, reason), как в GitHub-Example , который вызывается, когда паук завершил

def close(self, reason):
    mails_for_record = ""

    for mail in self.emails:
        mails_for_record += mail + "|"

    print(self.record + mails_for_record)

Обратите также внимание, я где-то читал, что для некоторых версий Scrapy это def close(self, reason), для других - def closed(self, reason).

Надеюсь, этот процесс поможет вам.

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