【问题标题】:How to pass information from one method to another in scrapy如何在scrapy中将信息从一种方法传递到另一种方法
【发布时间】:2020-05-08 15:34:57
【问题描述】:

我正在从需要我从个人候选人资料中获取数据的网站上抓取数据。问题是,一部分数据要从配置文件 sn-p 中提取,其余部分必须在进入配置文件后提取。

要使用 sn-p 提取的字段是: 1.工作授权 2. 候选人姓名 3. 图片ID

打开配置文件后即可提取其余数据。

问题:

我写了一个蜘蛛,想将上述字段的数据从一种方法传递到另一种方法。现在,当我抓取我的蜘蛛时,我会在特定页面上为所有候选配置文件重复这三个字段的数据。我实际上是网络抓取和 python 的新手。你能帮帮我吗?

我附上我的蜘蛛代码和 items.py 文件以供参考:

import scrapy
from urllib.parse import urljoin
from hbs_candidates.items import HbsCandidatesItem

domain = 'https://www.myvisajobs.com'
url = 'https://www.myvisajobs.com/CV/Search.aspx?DG=Bachelor&P=1'
page_scraped = 2
classes = ['HighLight: ', 'Membership: ', 'Honor: ', 'Skills: ', 'Degree: ', 'Career Level: ', 'Certification: ','Occupation: ', 'Reference: ', 'Target Locations: ', 'Career Title: ', 'Goal: ', 'Target Title:']


class InfoSpider(scrapy.Spider):
    name = 'inform'
    start_urls = [url]
    # page_no = 1

    def parse(self, response):
        wa_temp = []
        items = HbsCandidatesItem()
        tables = response.xpath("""//*[@id="ctl00_ctl00_ContentPlaceHolder1_ContentPlaceHolder1_divContent"]/center/table/tr""")
        names_temp = tables.css('b a::text').extract()
        images_temp = [domain + x for x in response.css('img::attr(src)').extract()[1:]]
        for i in range(len(tables)):
            wa = str(tables.xpath("""//*[@id="ctl00_ctl00_ContentPlaceHolder1_ContentPlaceHolder1_divContent"]/center/table/tr[3]/td[2]/text()[6]""").extract()).split('Work Authorization: ')[1]
            if wa is not None:
                temp_wa = wa
            else:
                temp_wa = 'N/A'
            wa_temp.append(temp_wa)
        my_list = response.css('b a::attr(href)').extract()
        for i in range(len(my_list)):
            url_final = urljoin(url, my_list[i])
            temp_url = response.urljoin(url_final)
            items['Candidate Name'] = names_temp[i]
            items['Image ID'] = images_temp[i]
            items['Work Authorization'] = wa_temp[i]
            request = scrapy.Request(temp_url, callback=self.parse_can_contents)
            request.cb_kwargs['items'] = items
            yield request

    def parse_can_contents(self, response, items):
        ### code to scrape data from profile page and assigning values to 
        items
        -----------
        -------------

        ## I want to access the values passed from parse method here    
        yield items

items.py 代码:

from scrapy.item import Item, Field


class HbsCandidatesItem(Item):
    def __setitem__(self, key, value):
        if key not in self.fields:
            self.fields[key] = Field()
        self._values[key] = value

我希望这很清楚。请问这个问题是否看起来模棱两可。谢谢!

【问题讨论】:

    标签: python web-scraping scrapy web-crawler metadata


    【解决方案1】:

    项目 (items = HbsCandidatesItem()) 应该在 for 循环中创建

    for i in range(len(my_list)):
            url_final = urljoin(url, my_list[i])
            temp_url = response.urljoin(url_final)
            items = HbsCandidatesItem()
            items['Candidate Name'] = names_temp[i]
            items['Image ID'] = images_temp[i]
            items['Work Authorization'] = wa_temp[i]
            request = scrapy.Request(temp_url, callback=self.parse_can_contents)
            request.cb_kwargs['items'] = items
            yield request
    

    【讨论】:

    • 谢谢,这成功了!你能解释一下为什么项目应该在 for 循环中吗?
    • 是的,因为您在 for 循环之外创建了 items 对象,并且在每个循环中,您都为同一个键分配了一个值。例如,在循环的每次迭代中,键 'Candidate Name' 的值总是在同一个对象中被替换,这样你就可以得到你“抓取”的所有记录的最后一个值。如果 item 对象是在循环内创建的,它的值不会在下一次迭代中被替换,因为它每次都是一个新对象。如果您对解决方案感到满意,可以将其标记为正确吗?)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-14
    • 2013-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-24
    相关资源
    最近更新 更多