Scrapy - FormRequest отправляет запрос GET, когда метод POST - PullRequest
1 голос
/ 01 июля 2019

Это страница, которую я хочу сканировать

Данные на странице поступают с этого URL

Это код моего сканера,Я проверял заголовки и форм-данные как минимум 5 раз.Я думаю, что они верны.Проблема заключается в том, что scopy отправляет запрос GET на start_url, хотя я переопределяю поведение по умолчанию метода parse.

class MySpider(CrawlSpider):

    name = 'myspider'

    start_urls = [
        'https://277kmabdt6-dsn.algolia.net/1/indexes/*/queries?x-algolia-agent=Algolia%20for%20vanilla%20JavaScript%20(lite)%203.27.1%3BJS%20Helper%202.26.0%3Bvue-instantsearch%201.7.0&x-algolia-application-id=277KMABDT6&x-algolia-api-key=bf8b92303c2418c9aed3c2f29f6cbdab',
    ]

    formdata = {
        'requests': [{'indexName': 'listings',
                      'params': 'query=&hitsPerPage=24&page=0&highlightPreTag=__ais-highlight__&highlightPostTag=__%2Fais-highlight__&filters=announce_type%3Aproperty-announces%20AND%20language_code%3Apt%20AND%20listing_id%3A%205&facets=%5B%22announce_type%22%5D&tagFilters='}]
    }
    headers = {
        'accept': 'application/json',
        'content-type': 'application/x-www-form-urlencoded',
        'Origin': 'https://www.flat.com.br',
        'Referer': 'https://www.flat.com.br/search?query=',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
    }


    def parse(self, response):
        for url in self.start_urls:
            yield scrapy.FormRequest(
                url=url,
                method='POST',
                headers=self.headers,
                formdata=self.formdata,
                callback=self.parse_page,
            )

    def parse_page(self, response):

        print json.loads(response.text)

Это сообщение, которое я получаю, когда запускаю паука.

Мои вопросы;Почему скрап отправляет на URL GET запрос, я что-то упустил?Может ли быть какая-то другая причина, почему мой запрос не выполняется?

2019-07-01 11:45:58 [scrapy] DEBUG: Crawled (400) <GET https://277kmabdt6-dsn.algolia.net/1/indexes/*/queries?x-algolia-agent=Algolia%20for%20vanilla%20JavaScript%20(lite)%203.27.1%3BJS%20Helper%202.26.0%3Bvue-instantsearch%201.7.0&x-algolia-application-id=277KMABDT6&x-algolia-api-key=bf8b92303c2418c9aed3c2f29f6cbdab> (referer: None)
2019-07-01 11:45:58 [scrapy] DEBUG: Ignoring response <400 https://277kmabdt6-dsn.algolia.net/1/indexes/*/queries?x-algolia-agent=Algolia%20for%20vanilla%20JavaScript%20(lite)%203.27.1%3BJS%20Helper%202.26.0%3Bvue-instantsearch%201.7.0&x-algolia-application-id=277KMABDT6&x-algolia-api-key=bf8b92303c2418c9aed3c2f29f6cbdab>: HTTP status code is not handled or not allowed

Ответы [ 3 ]

2 голосов
/ 01 июля 2019

Вам необходимо переименовать ваш метод parse в start_requests, потому что по умолчанию Scrapy будет GET для каждого URL-адреса из self.start_urls:

def start_requests(self):
    for url in self.start_urls:
        yield scrapy.FormRequest(
            url=url,
            method='POST',
            headers=self.headers,
            formdata=self.formdata,
            callback=self.parse_page,
        )
1 голос
/ 01 июля 2019

Сначала переименуйте ваш метод синтаксического анализа в:

def start_requests(self):

При отправке формы вам следует использовать scrapy.FormRequest.Вы хотите использовать метод = post, только если у вас есть необработанное тело, которое вы хотите отправить.В этом случае это выглядит как данные ofrm, поэтому сделайте что-то подобное.

    formdata = {
        'requests': [{'indexName': 'listings',
        'params': 'query=&hitsPerPage=24&page=0&highlightPreTag=__ais-highlight__&highlightPostTag=__%2Fais-highlight__&filters=announce_type%3Aproperty-announces%20AND%20language_code%3Apt%20AND%20listing_id%3A%205&facets=%5B%22announce_type%22%5D&tagFilters='}]
    }
    headers = {
        'accept': 'application/json',
        'content-type': 'application/x-www-form-urlencoded',
        'Origin': 'https://www.flat.com.br',
        'Referer': 'https://www.flat.com.br/search?query=',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
    }

def start_requests(self):
    for link in self.start_urls:
        yield scrapy.FormRequest(link, headers=headers, formdata=formdata, callback=self.parse_page)

Есть и другие инструменты, которые вы можете использовать, такие как запрос формы из ответа, которые могут помочь в этом.Если вы хотите отправить необработанную строку json или что-то еще, вам нужно преобразовать свой словарь в строку, а затем установить метод на POST, как вы сделали здесь.FormRequest автоматически отправит запрос POST, и он может быть разумным, если вы используете функции ответа from.

Ссылки: https://docs.scrapy.org/en/latest/topics/request-response.html#request-subclasses

1 голос
/ 01 июля 2019

Я думаю, что вы можете получить действительный ответ только тогда, когда ваша полезная нагрузка будет body=json.dumps(self.formdata) вместо formdata=self.formdata, как они представлены в формате json.Рекомендуемая часть должна быть похожа на следующую:1009 * никогда не будет проходить через parse() метод, поскольку он выдаст ошибку статуса 400 или что-то в этом роде.Итак, чтобы использовать метод parse(), как вы пытались, убедитесь, что url, который вы использовали в start_urls, способен получить желаемый статус.Тем не менее, даже если вы используете другой url со статусом 200, а затем обрабатываете почтовые запросы с помощью right url, тогда ответ будет таким, как нужно.

import json
import scrapy

class MySpider(scrapy.Spider):
    name = 'myspider'

    #different url

    start_urls = ['https://stackoverflow.com/questions/tagged/web-scraping']
    url = 'https://277kmabdt6-dsn.algolia.net/1/indexes/*/queries?x-algolia-agent=Algolia%20for%20vanilla%20JavaScript%20(lite)%203.27.1%3BJS%20Helper%202.26.0%3Bvue-instantsearch%201.7.0&x-algolia-application-id=277KMABDT6&x-algolia-api-key=bf8b92303c2418c9aed3c2f29f6cbdab'

    formdata = {
        'requests': [{'indexName': 'listings',
        'params': 'query=&hitsPerPage=24&page=0&highlightPreTag=__ais-highlight__&highlightPostTag=__%2Fais-highlight__&filters=announce_type%3Aproperty-announces%20AND%20language_code%3Apt%20AND%20listing_id%3A%205&facets=%5B%22announce_type%22%5D&tagFilters='}]
    }
    headers = {
        'accept': 'application/json',
        'content-type': 'application/x-www-form-urlencoded',
        'Origin': 'https://www.flat.com.br',
        'Referer': 'https://www.flat.com.br/search?query=',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
    }

    def parse(self,response):
        yield scrapy.Request(
                url=self.url,method='POST',
                headers=self.headers,body=json.dumps(self.formdata),
                callback=self.parse_page,
            )

    def parse_page(self, response):
        print(json.loads(response.text))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...