เอาต์พุตฟีด Scrapy มีเอาต์พุตที่คาดหวังหลายครั้งแทนที่จะเป็นเพียงครั้งเดียว

ฉันได้เขียนสไปเดอร์ซึ่งมีจุดประสงค์เพียงอย่างเดียวคือการดึงตัวเลขหนึ่งตัวจาก http://www.funda.nl/koop/amsterdam/ กล่าวคือ จำนวนหน้าสูงสุดจากเพจเจอร์ที่ด้านล่าง (เช่น หมายเลข 255 ในตัวอย่างด้านล่าง)

ป้อนคำอธิบายรูปภาพที่นี่

ฉันจัดการเพื่อทำสิ่งนี้โดยใช้ LinkExtractor ตามนิพจน์ทั่วไปที่ URL ของเพจเหล่านี้ตรงกัน แมงมุมแสดงไว้ด้านล่าง:

import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.crawler import CrawlerProcess
from Funda.items import MaxPageItem

class FundaMaxPagesSpider(CrawlSpider):
    name = "Funda_max_pages"
    allowed_domains = ["funda.nl"]
    start_urls = ["http://www.funda.nl/koop/amsterdam/"]

    le_maxpage = LinkExtractor(allow=r'%s+p\d+' % start_urls[0])   # Link to a page containing thumbnails of several houses, such as http://www.funda.nl/koop/amsterdam/p10/

    rules = (
    Rule(le_maxpage, callback='get_max_page_number'),
    )

    def get_max_page_number(self, response):
        links = self.le_maxpage.extract_links(response)
        max_page_number = 0                                                 # Initialize the maximum page number
        page_numbers=[]
        for link in links:
            if link.url.count('/') == 6 and link.url.endswith('/'):         # Select only pages with a link depth of 3
                page_number = int(link.url.split("/")[-2].strip('p'))       # For example, get the number 10 out of the string 'http://www.funda.nl/koop/amsterdam/p10/'
                page_numbers.append(page_number)
                # if page_number > max_page_number:
                #     max_page_number = page_number                           # Update the maximum page number if the current value is larger than its previous value
        max_page_number = max(page_numbers)
        print("The maximum page number is %s" % max_page_number)
        yield {'max_page_number': max_page_number}

หากฉันรันสิ่งนี้ด้วยฟีดเอาต์พุตโดยป้อน scrapy crawl Funda_max_pages -o funda_max_pages.json ที่บรรทัดคำสั่ง ไฟล์ JSON ผลลัพธ์จะมีลักษณะดังนี้:

[
{"max_page_number": 257},
{"max_page_number": 257},
{"max_page_number": 257},
{"max_page_number": 257},
{"max_page_number": 257},
{"max_page_number": 257},
{"max_page_number": 257}
]

ฉันพบว่ามันแปลกที่ dict ถูกส่งออก 7 ครั้งแทนที่จะเป็นเพียงครั้งเดียว ท้ายที่สุดแล้ว คำสั่ง yield อยู่นอกลูป for ใครสามารถอธิบายพฤติกรรมนี้ได้บ้าง


person Kurt Peek    schedule 14.07.2016    source แหล่งที่มา


คำตอบ (2)


  1. สไปเดอร์ของคุณไปที่ start_url แรก
  2. ใช้ LinkExtractor เพื่อแยก 7 URL
  3. ดาวน์โหลดทุก URL ทั้ง 7 รายการและการโทร get_max_page_number ในทุกรายการ
  4. สำหรับทุก ๆ url get_max_page_number จะส่งกลับพจนานุกรม
person Granitosaurus    schedule 14.07.2016

เพื่อเป็นวิธีแก้ปัญหา ฉันได้เขียนเอาต์พุตลงในไฟล์ข้อความที่จะใช้แทนเอาต์พุตฟีด JSON:

import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.crawler import CrawlerProcess

class FundaMaxPagesSpider(CrawlSpider):
    name = "Funda_max_pages"
    allowed_domains = ["funda.nl"]
    start_urls = ["http://www.funda.nl/koop/amsterdam/"]

    le_maxpage = LinkExtractor(allow=r'%s+p\d+' % start_urls[0])   # Link to a page containing thumbnails of several houses, such as http://www.funda.nl/koop/amsterdam/p10/

    rules = (
    Rule(le_maxpage, callback='get_max_page_number'),
    )

    def get_max_page_number(self, response):
        links = self.le_maxpage.extract_links(response)
        max_page_number = 0                                                 # Initialize the maximum page number
        for link in links:
            if link.url.count('/') == 6 and link.url.endswith('/'):         # Select only pages with a link depth of 3
                print("The link is %s" % link.url)
                page_number = int(link.url.split("/")[-2].strip('p'))       # For example, get the number 10 out of the string 'http://www.funda.nl/koop/amsterdam/p10/'
                if page_number > max_page_number:
                    max_page_number = page_number                           # Update the maximum page number if the current value is larger than its previous value
        print("The maximum page number is %s" % max_page_number)
        place_name = link.url.split("/")[-3]                                # For example, "amsterdam" in 'http://www.funda.nl/koop/amsterdam/p10/'
        print("The place name is %s" % place_name)
        filename = str(place_name)+"_max_pages.txt"                         # File name with as prefix the place name
        with open(filename,'wb') as f:
            f.write('max_page_number = %s' % max_page_number)               # Write the maximum page number to a text file
        yield {'max_page_number': max_page_number}

process = CrawlerProcess({
    'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'
})

process.crawl(FundaMaxPagesSpider)
process.start() # the script will block here until the crawling is finished

ฉันยังดัดแปลงสไปเดอร์เพื่อรันเป็นสคริปต์ด้วย สคริปต์จะสร้างไฟล์ข้อความ amsterdam_max_pages.txt โดยมีบรรทัดเดียว max_page_number: 257

person Kurt Peek    schedule 14.07.2016
comment
คุณยังคงรวบรวมข้อมูล 7 URL แต่คุณกำลังแทนที่ไฟล์เดียวกันด้วย max_page_number: 257 7 ครั้ง... - person Granitosaurus; 14.07.2016