Невозможно записать в глобальную переменную из метода Python Scrapy - PullRequest
0 голосов
/ 11 января 2020

Я определил метод scrapy, который я ожидаю записать в глобальную переменную:

Я установил глобальную переменную со значением заполнителя

currentTitle = 'unchanged global title'

Затем я определил паук scrapy

class QuotesSpider(scrapy.Spider):
    name = "quotes"
    currentClassTitle = 'unchanged class title'

    def start_requests(self):
        urls = [
            #here goes my list of urls to scrape
        ]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        title=response.xpath('/html/head/title').getall()
        title=str(title)
        title=title[9:-10]
        print(title)
        #So far so good, the title is correctly extracted and printed
        #I intend to write the title to both global currentTitle variable
        # and to class variable currentClassTitle, using method update for the latter:

        global currentTitle
        currentTitle = title
        QuotesSpider.update(title)

    def update(value):
        QuotesSpider.currentClassTitle = value

Далее следуют стандартные скрапы, с которыми я не очень хорошо знаком, но работал хорошо, пока не наткнулся на эту проблему

def crawl ():
    process = CrawlerProcess({
        'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'
    })

    process.crawl(QuotesSpider)
    process.start() # the script will block here until the crawling is finished
    time.sleep(2)

def run_spider(spider):
    def f(q):
        try:
            runner = crawler.CrawlerRunner()
            deferred = runner.crawl(spider)
            deferred.addBoth(lambda _: reactor.stop())
            reactor.run()
            q.put(None)
        except Exception as e:
            q.put(e)

    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    result = q.get()
    p.join()

    if result is not None:
        raise result

Ниже приведена функция, которая вызывает скребок всякий раз, когда какой-либо документ определенной коллекции Google Firestore имеет сканируемое значение: False (которое меняется на True)

def on_snapshot(col_snapshot, changes, read_time):
    docCounter = 0
    for doc in col_snapshot:
        print(u'{}'.format(doc.id))
        thisDoc_ref = db.collection(u'urls').document(doc.id)
        thisDoc_ref.update({u'capital': 'sample capital name'})
        thisDoc_ref.update({u'crawled': True})
        run_spider(QuotesSpider)
        sleep(5)
        #Just to ensure that I give the crawler enough time to process, the function sleeps after triggering the spider. 
        #Not the best practice, but good enough for testing functionality for the moment

        print(QuotesSpider.currentClassTitle)
#I get 'unchanged class title'

        print(currentTitle)
#I get 'unchanged global title'

        thisDoc_ref.update({u'title': currentTitle})
#I intend to store the document's title in Firestore using the value of currentTitle, which will not work
#because I cannot retrieve the value of title

Что бы ни работало, получение значения заголовка из атрибута класса QuotesSpider.currentClassTitle или глобальная переменная currentTitle помогут мне, но ни одна из них не сработает. Кажется, я не могу обновить значение любого из них при запуске паука.

1 Ответ

0 голосов
/ 15 января 2020

Если вы хотите получить доступ к вашей переменной, указывающей c к вашему экземпляру вашего Python класса внутри одного из его методов класса, вы хотите использовать

self.currentClassTitle

Использование QuotesSpider.currentClassTitle обращается к переменной класса по умолчанию (если ваш класс не инициализирован)

Дополнительная информация здесь: https://www.geeksforgeeks.org/self-in-python-class/

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