刮刮多页Scrapy

时间:2017-02-08 06:06:58

标签: python web-scraping scrapy scrapy-spider

我正在努力争取每年顶级Billboard排名前100位。我有一个文件可以一次使用一年,但我希望它能够遍历所有年份并收集这些数据。这是我目前的代码:

from scrapy import Spider
from scrapy.selector import Selector
from Billboard.items import BillboardItem
from scrapy.exceptions import CloseSpider
from scrapy.http import Request

URL = "http://www.billboard.com/archive/charts/%/hot-100"

class BillboardSpider(Spider):
    name = 'Billboard_spider'
    allowed_urls = ['http://www.billboard.com/']
    start_urls = [URL % 1958]

def _init_(self):
            self.page_number=1958

def parse(self, response):
            print self.page_number
            print "----------"

    rows = response.xpath('//*[@id="block-system-main"]/div/div/div[2]/table/tbody/tr').extract()

    for row in rows:
        IssueDate = Selector(text=row).xpath('//td[1]/a/span/text()').extract()
        Song = Selector(text=row).xpath('//td[2]/text()').extract()
        Artist = Selector(text=row).xpath('//td[3]/a/text()').extract()


        item = BillboardItem()
        item['IssueDate'] = IssueDate
        item['Song'] = Song
        item['Artist'] = Artist


        yield item
            self.page_number += 1
            yield Request(URL % self.page_number)

但我收到错误:“start_urls = [URL%1958] ValueError:索引41“

时不支持的格式字符'/'(0x2f)

有什么想法吗?我希望代码能够从原来的“URL”链接自动将年份更改为1959年,并逐年继续,直到它停止查找表格,然后关闭。

1 个答案:

答案 0 :(得分:4)

您获得的错误是因为您没有使用正确的字符串格式语法。您可以查看here了解其工作原理的详细信息。 它在您的特定情况下不起作用的原因是您的网址缺少'

URL = "http://www.billboard.com/archive/charts/%/hot-100"

应该是

URL = "http://www.billboard.com/archive/charts/%s/hot-100"

无论如何,最好使用新的字符串格式:

URL = "http://www.billboard.com/archive/charts/{}/hot-100"
start_urls = [URL.format(1958)]

继续,您的代码还有其他一些问题:

def _init_(self):
    self.page_number=1958

如果您想使用init函数,则应将其命名为__init__(两个下划线),并且因为您正在扩展Spider,您需要传递{{1} }和*args所以你可以调用父构造函数:

**kwargs

听起来你可能最好不要使用def __init__(self, *args, **kwargs): super(MySpider, self).__init__(*args, **kwargs) self.page_number = 1958 而只是使用列表comprehension来生成get go中的所有网址:

__init__

start_urls = ["http://www.billboard.com/archive/charts/{year}/hot-100".format(year=year) for year in range(1958, 2017)] 将如下所示:

start_urls

您还没有正确填充['http://www.billboard.com/archive/charts/1958/hot-100', 'http://www.billboard.com/archive/charts/1959/hot-100', 'http://www.billboard.com/archive/charts/1960/hot-100', 'http://www.billboard.com/archive/charts/1961/hot-100', ... 'http://www.billboard.com/archive/charts/2017/hot-100'] ,因为对象不支持(默认情况下)支持项目分配:

BillboardItem

应该是:

 item = BillboardItem()
 item['IssueDate'] = IssueDate
 item['Song'] = Song
 item['Artist'] = Artist

虽然在课堂上这样做通常会更好[&p; init函数:     class BillboardItem(object):         def init (self,issue_date,song,artist):             self.issue_date = issue_date             self.song =歌曲             self.artist =艺术家 然后按item = BillboardItem() item.IssueDate = IssueDate item.Song = Song item.Artist = Artist

创建项目

更新

无论如何,我清理了你的代码(并创建了一个BillboardItem,因为我不知道你的代码如何):

item = BillboardItem(IssueDate, Song, Artist)

希望这会有所帮助。 :)