Как использовать JSON, содержащий URL и ID, в Scrapy и структурировать результаты? - PullRequest
0 голосов
/ 12 марта 2019

Я использую Scrapy для очистки данных из 9000+ URL-адресов, содержащихся в JSON с соответствующим идентификатором. Вот мой тип объекта JSON:

[{
"objectID": 10500,
"gm_url": "https://reddit.com/1"
},
"objectID": 10501,
"gm_url": "https://reddit.com/2"
}]

Я бы хотел, чтобы мои результаты были в формате json со соскребенными данными, соответствующим URL и идентификатором.

[{
    "objectID": 10500,
    "gm_url": "https://reddit.com",
    "results": [
        {
            "model": "",
            "price": "",
            "auction": "",
            "date": "",
            "auction_url": "",
            "img": ""
        },
        {
            "model": "",
            "price": "",
            "auction": "",
            "date": "",
            "auction_url": "",
            "img": ""
        },
        {
            "model": "",
            "price": "",
            "auction": "",
            "date": "",
            "auction_url": "",
            "img": ""
        }
    ]
}]

Вот мой код прямо сейчас в скрапе (что-то вроде грязного):

import json
import scrapy

with open('/home/bolgi/Workspace/Dev/python_workspace/gm_spider/Json/db_urls_glenmarch_results_scrapy_reduced.json', encoding='utf-8') as data_file:
    data = json.load(data_file)

for item in data:
    objectId = item['objectID']
    gmUrl = item['gm_url']

    class GlenMarchSpider(scrapy.Spider):
        name = 'glenmarch'

        def start_requests(self):
            start_urls = gmUrl

            for url in start_urls:
                yield scrapy.Request(url, callback=self.parse)

        def parse(self, response):
            for caritem in response.css("div.car-item-border"):
                yield {
                    "url": response.url,
                    "model": caritem.css("div.make::text").get(),
                    "price": caritem.css("div.price::text").get(),
                    "auction": caritem.css("div.auctionHouse::text").get(),
                    "date": caritem.css("div.date::text").get(),
                    "auction_url": caritem.css("div.view-auction a::attr(href)").get(),
                    "img": caritem.css("img.img-responsive::attr(src)").get()
                }

Я не знаю, как структурировать код и как использовать файл JSON, я новичок в python, и это немного сложно для меня.

Ответы [ 2 ]

1 голос
/ 12 марта 2019

Вы никогда не должны объявлять класс внутри forloop.

Предлагаю вам следующую структуру:

import json
import scrapy

class GlenMarchSpider(scrapy.Spider):
    name = 'glenmarch'

    def __init__(self):
        with open('/home/bolgi/Workspace/Dev/python_workspace/gm_spider/Json/db_urls_glenmarch_results_scrapy_reduced.json', encoding='utf-8') as data_file:
            self.data = json.load(data_file)

    def start_requests(self):
        for item in self.data:
            request = scrapy.Request(item['gm_url'], callback=self.parse)
            request.meta['item'] = item
            yield request

    def parse(self, response):
        item = response.meta['item']
        item['results'] = []
        for caritem in response.css("div.car-item-border"):
            item['results'].append({
                "model": caritem.css("div.make::text").get(),
                "price": caritem.css("div.price::text").get(),
                "auction": caritem.css("div.auctionHouse::text").get(),
                "date": caritem.css("div.date::text").get(),
                "auction_url": caritem.css("div.view-auction a::attr(href)").get(),
                "img": caritem.css("img.img-responsive::attr(src)").get()
            })
        yield item

Затем вы можете вызвать своего паука (и сохранить его в новом файле json):

$ scrapy crawl glenmarch -o myjson.json -t json

Если в коде есть вещи, которые вы не понимаете, не стесняйтесь обращаться за разъяснениями! :)

0 голосов
/ 12 марта 2019

scrapy.spider также имеет поле списка start_urls, которое по умолчанию пустое, где вы можете добавить все urls.

import scrapy
import json

class GlenMarchSpider(scrapy.Spider)
    name = 'glenmarch'
    start_urls = []

    with open('/home/bolgi/Workspace/Dev/python_workspace/gm_spider/Json/db_urls_glenmarch_results_scrapy_reduced.json', encoding='utf-8') as json_file:
         data = json.load(json_file)
         for item in data:
             objectId = item['objectID']
             gmUrl = item['gm_url']
             start_urls.append(gmUrl)

    def parse(self, response):
        item = {}
        for caritem in response.css("div.car-item-border"):
            yield {
                "url": response.url,
                "model": caritem.css("div.make::text").get(),
                "price": caritem.css("div.price::text").get(),
                "auction": caritem.css("div.auctionHouse::text").get(),
                "date": caritem.css("div.date::text").get(),
                "auction_url": caritem.css("div.view-auction a::attr(href)").get(),
                "img": caritem.css("img.img-responsive::attr(src)").get()
            }

И вы тоже можете запустить паука:

scrapy runspider quotes_spider.py -o glenmarch.json

Для получения более подробной информации, пожалуйста, ознакомьтесь с официальным документом или не стесняйтесь спрашивать. https://scrapy.readthedocs.io/en/latest/intro/overview.html

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