Scrapy - отсутствуют данные после формы запроса - PullRequest
1 голос
/ 02 апреля 2019

Я использую этот веб-сайт для определения широты и долготы разных городов: https://www.latlong.net/.

Вот мой код:

import scrapy
import json

with open('C:/Users/coppe/tutorial/cities.json') as json_file:  
    cities = json.load(json_file)

class communes_spider(scrapy.Spider):
    name = "geo"
    start_urls = ['https://www.latlong.net/']

    def parse(self, response):
        for city in cities:
            yield scrapy.FormRequest.from_response(response, formid='place', formdata={'place': city['city']}, callback=self.get_geo)

    def get_geo(self, response):
        yield {'coord': response.css('input::text').get()}        

Код работает нормально, но выводполучить не правильно.Выходное значение по умолчанию (0,0) и должно быть что-то вроде (50.643909, 5.571560) после формы.Однако сканер все еще собирает (0,0) в качестве ответа.Я предполагаю, что проблема исходит от веб-сайта, но я не могу идентифицировать это.

Пример JSON:

[{"city": "Anvers, BE"},
{"city": "Gand, BE"},
{"city": "Charleroi, BE"},
{"city": "Li\u00e8ge, BE"},
{"city": "Ville de Bruxelles, BE"},
{"city": "Schaerbeek, BE"},
{"city": "Anderlecht, BE"},
{"city": "Bruges, BE"},
{"city": "Namur, BE"},
{"city": "Louvain, BE"},
{"city": "Molenbeek-Saint-Jean, BE"}]

1 Ответ

1 голос
/ 02 апреля 2019

Вы можете попробовать этот код, это работает на моей стороне:

# -*- coding: utf-8 -*-
import re
import json

import scrapy

class communes_spider(scrapy.Spider):
    name = "geo"
    allowed_domains = ["www.latlong.net"]
    start_urls = ['https://www.latlong.net/']

    custom_settings = {
        'COOKIES_ENABLED': True,
    }

    # This regex is not perfect and can be improved
    LAT_LONG_REGEX = 'sm\((?P<lat>-?\d+\.?\d+),(?P<long>-?\d+\.?\d+)'

    def start_requests(self):
        FILE_PATH = 'C:/Users/coppe/tutorial/cities.json'
        with open(FILE_PATH) as json_file:
            cities_data = json.load(json_file)
        for d in cities_data:
            yield scrapy.Request(
                url='https://www.latlong.net/',
                callback=self.gen_csrftoken,
                meta={'city': d['city']},
                dont_filter=True, # Allow to request multiple time the same URL
            )

    def gen_csrftoken(self, response):
        city = response.meta['city']
        yield scrapy.FormRequest.from_response(
            response,
            formid='frmPlace',
            formdata={'place': city},
            callback=self.get_geo,
            meta={'city': city}
        )

    def get_geo(self, response):
        lat_long_search = re.search(self.LAT_LONG_REGEX, response.body.decode('utf-8'))
        if lat_long_search:
            yield {
                'coord': (lat_long_search.group('lat'), lat_long_search.group('long')),
                'city': response.meta['city']
            }
        else:
            # Something is wrong, you can investigate with `inspect_response`
            from scrapy.shell import inspect_response
            inspect_response(response, self)

Причина, по которой вы находите (0, 0), заключается в том, что координаты широты / долготы отображаются через javascript (они заполняются)из бэкэнда внутри шаблона).Scrapy не может выполнить JavaScript без Splash .

Итак, в основном мы выполняем синтаксический анализ сценария JS с помощью Regex, чтобы найти значения lat / long.

(если вы находите этот ответ полезным, не забудьте пометить его как принятый).) * +1010 *

...