簡體   English   中英

使用 scrapy 抓取網站時,如何動態生成請求?

[英]When scraping website using scrapy, How to generate request dynamically?

我正在嘗試使用scrapy從網站上抓取數據。 但是頁面是使用請求生成的,這意味着 url + 其他數據(我發現使用瀏覽器的開發人員工具)。 我將請求復制為 cURL 並使用 curl 將其轉換為scrapy 到 Z3CD13A277FBC2FEA5EF643648C鏈接。 當我手動創建請求然后獲取時,我可以從這些頁面獲取數據。 所以我需要手動創建請求。 我的問題是如何在蜘蛛中動態創建請求。

class PowerGenerationSpider(scrapy.Spider):
    name = "power_generation"
    # make request
    url = 'http://my/website'

headers = {
    "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0",
    "Accept": "application/json, text/plain, */*",
    "Accept-Language": "en-US,en;q=0.5",
    "Authorization": "authorization_string",
    "Content-Type": "application/json",
    "Origin": "http://my/website",
    "DNT": "1",
    "Connection": "keep-alive",
    "Referer": "mywebsite"
}
# need to run this for month 01 to 10 or how can i change this programatically
body = '{"month":"01","year":"2020","user_id":"vishvajeet"}'

request = scrapy.Request(
    url=url,
    method='POST',
    dont_filter=True,
    headers=headers,
    body=body,
)

def start_requests(self):
    yield self.request #scrapy.Request(self.request, self.parse)

def parse(self, response):
    data = json.loads(response.text)
    solar_energy_datalist = data["resultObject"]
    item = PowerGenerationItem()
    for solar_energy_data in solar_energy_datalist:
        date = solar_energy_data['date']
        power_generation = solar_energy_data['power_generation']

        item['date'] = date
        item['power_generation'] = power_generation
        yield item

如何在請求正文中生成具有不同參數的請求並將其傳遞給抓取以供下一個抓取請求。 注意:我在 web 上找到了其他資源,它告訴如何動態生成 url。 這與 url 無關,我想生成請求,因為 URL 是相同的。

編輯 1:我轉換為 scrapy 請求的 cURL 如下。 我稍后可能會刪除身份驗證相關信息。

curl 'http://3.6.0.2/inject-solar-angular/inject_solar_server/graph/Graph/cumulative_month_graph' -H 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0' -H 'Accept: application/json, text/plain, */*' -H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjkwIiwicm9sZSI6IjQiLCJ0aW1lc3RhbXAiOjE1OTU1NjcxMjEsInN0YXR1cyI6MX0.-RFFUc69PxDsAk_zmn3VI8OqUh-mYkYioFyTSBU17_s' -H 'Content-Type: application/json' -H 'Origin: http://www.injectsolar.com' -H 'DNT: 1' -H 'Connection: keep-alive' -H 'Referer: http://www.injectsolar.com/portal/' --data-raw '{"month":"01","year":"2020","user_id":"triose"}'

編輯:2

我正在嘗試每天獲取 1 月 20 日至 6 月 20 日的發電數據。 為此,我需要更改體內的參數。 如果在正文目錄中月份=01,它會給出 1 月 20 日的數據。 如果我將其更改為月 = 02,它會給我 2 月的數據。 但我想通過爬蟲自動執行此操作。 就好像爬蟲從一頁爬到另一頁一樣。 它應該給我這樣的數據。

關於提供的代碼的一些事情。 我希望您提供更多代碼來嘗試動態生成具有不同主體參數的請求。 這是我在你的代碼中還沒有看到的東西,所以我能提供的幫助只有這么多。 但是這里的文本足以向您展示如何將您想要的任何信息從一個 function 傳輸到另一個,因此您應該能夠進行嘗試。

作為另一個免責聲明,因為我沒有 URL,我無法自己運行此代碼,因此如果有問題,也很難取消選擇。

更正

  1. 只需將 scrapy 請求放入start_requests function
  2. 引用 function 之外的變量需要添加 self.VARIABLE。 在這種情況下self.headers
  3. 要輸入參數,您需要使用元參數。 所以cb_kwargs = self.body cb_kwargs參數用於將您想要的任何信息字典從一個 function 傳輸到另一個。 Headers 是scrapy.Request中定義的參數,因此不適用於該參數。 但是您創建的正文字典是用戶創建的信息,並且 cb_kwargs 參數適用於此。
  4. 您需要為要處理的響應定義一個回調。 這里我們將回調定義為self.parse ,它是start_requests function 的默認回調。
  5. 除非 url 與start_urls中的 URL 不同。 請參閱 scrapy.Request 中的 URL 參數作為self.start_urls[0] 在這種情況下,您已經定義了變量 url,因此在您的scrapy.Request中,您需要將其稱為self.url

代碼示例

   class PowerGenerationSpider(scrapy.Spider):
        name = "power_generation"
        # make request
        url = 'http://my/website'

        headers = {
           "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0",
           "Accept": "application/json, text/plain, */*",
           "Accept-Language": "en-US,en;q=0.5",
           "Authorization": "authorization_string",
           "Content-Type": "application/json",
           "Origin": "http://my/website",
           "DNT": "1",
           "Connection": "keep-alive",
           "Referer": "mywebsite"
              }
   # need to run this for month 01 to 10 or how can i change this programatically
        body = {"month":"01","year":"2020","user_id":"vishvajeet"}



        def start_requests(self):
             yield scrapy.Request(
                              url=self.url,
                              method='POST',
                              dont_filter=True,
                              headers=self.headers,
                              cb_kwargs=self.body,
                              callback=self.parse
                             )

        def parse(self, response):
            data = json.loads(response.text)
            solar_energy_datalist = data["resultObject"]
            item = PowerGenerationItem()
            for solar_energy_data in solar_energy_datalist:
                date = solar_energy_data['date']
                power_generation = solar_energy_data['power_generation']

                item['date'] = date
                item['power_generation'] = power_generation
                yield item

附加信息

  1. 請記住, start_requests function 用於生成對 start_urls 的請求。

  2. self.VARIABLE來自於對類的了解。 理解這意味着什么對於遵循這個例子至關重要。 The beauty of self.VARIABLE means that if you define a variable in a class that is NOT within a funtion in the class, it can be used in ANY function within the class but you have to remember to refer to as self.VARIABLE in each function。 這種類型的變量稱為 class 變量。

  3. 如果您需要修改 scrapy 給您的響應,或者想要對提取的數據應用一個小的 function 以清理它,請考慮使用 ItemLoaders 提取數據。 ItemLoaders 讓您可以更自由地更改 scrapy 響應的輸出。

額外學習資源

  1. 有關 class 變量的更多信息,請參見此處
  2. 閱讀 scrapy 的scrapy.Request文檔。如果您仔細閱讀此處的請求,它將在此處解釋有關 cb_kwargs 的信息,但您也應該更好地了解您可以使用的 arguments。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM