Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 索引器在对绝对链接使用Scrapy时_Python_Json_Xpath_Scrapy - Fatal编程技术网

Python 索引器在对绝对链接使用Scrapy时

Python 索引器在对绝对链接使用Scrapy时,python,json,xpath,scrapy,Python,Json,Xpath,Scrapy,我正在从维基百科上抓取一个网页,特别是一个使用Python库的网页。以下是原始代码: import scrapy from wikipedia.items import WikipediaItem class MySpider(scrapy.Spider): name = "wiki" allowed_domains = ["en.wikipedia.org/"] start_urls = [ 'https://en.wikipedia.org/wik

我正在从维基百科上抓取一个网页,特别是一个使用Python库的网页。以下是原始代码:

import scrapy
from wikipedia.items import WikipediaItem


class MySpider(scrapy.Spider):
    name = "wiki"
    allowed_domains = ["en.wikipedia.org/"]
    start_urls = [
        'https://en.wikipedia.org/wiki/Category:2013_films',
    ]

    def parse(self, response):
        titles = response.xpath('//div[@id="mw-pages"]//li')
        items = []
        for title in titles:
            item = WikipediaItem()
            item["title"] = title.xpath("a/text()").extract()
            item["url"] = title.xpath("a/@href").extract()
            items.append(item)
        return items
然后在终端中,我运行scrapy crawl wiki-o wiki.json-t json将数据输出到json文件。代码运行时,分配给url键的链接都是相对链接。i、 e.:{url:[/wiki/9_Full_Moons],标题:[9 Full Moons]}

我需要的不是/wiki/9_满月。因此,我修改了上述代码以从URLPASSE库导入urljoin。我还将for循环修改为如下所示:

for title in titles:
    item = WikipediaItem()
    url = title.xpath("a/@href").extract()
    item["title"] = title.xpath("a/text()").extract()
    item["url"] = urljoin("http://en.wikipedia.org", url[0])
    items.append(item)
return(items)
我认为这是正确的方法,因为分配给url键的数据类型包含在括号中,这将包含一个列表,对吗?因此,为了获取其中的字符串,我键入了url[0]。然而,这次我得到了一个索引器,它看起来像这样:

索引器:列表索引超出范围


有人能帮我解释一下哪里出错了吗?

我想你可以把两个字符串连接起来,而不是使用urljoin。试试这个:

for title in titles:
    item = WikipediaItem()
    item["title"] = title.xpath("a/text()").extract()
    item["url"] = "http://en.wikipedia.org" + title.xpath("a/@href").extract()[0]
    items.append(item)
return(items)

在使用相对链接的第一次代码迭代中,您使用了xpath方法:item[url]=title.xpatha//@href.extract 返回的对象是我假设的字符串列表,因此索引它将是有效的

在新的迭代中,您使用了select方法:url=title.selecta//href.extract,然后使用url[0]将返回的对象视为一个iterable。检查select方法返回的内容,可能是一个列表,如前一个示例中所示


注:是您的朋友。

因此,在将代码镜像到文档中给出的示例后,我能够使代码正常工作:

def parse(self, response):
    for text in response.xpath('//div[@id="mw-pages"]//li/a/text()').extract():
        yield WikipediaItem(title=text)
    for href in response.xpath('//div[@id="mw-pages"]//li/a/@href').extract():
        link = urljoin("http://en.wikipedia.org", href)
        yield WikipediaItem(url=link)
如果有人需要进一步澄清Items类是如何工作的

此外,尽管代码有效,但它不会将标题与其相应的链接配对。所以它会给你

标题,标题,标题,链接,链接,链接

而不是

标题,链接,标题,链接,标题,链接


后者可能是更理想的结果——但这是另一个问题。如果有人提出了一个比我更好的解决方案,我将非常乐意听取你的答案!谢谢

为了更好地澄清,我将修改上述代码

for title in titles:
    item = WikipediaItem()
    item["title"] = title.xpath("a/text()").extract()
    item["url"] = "http://en.wikipedia.org" + title.xpath("a/@href").extract()[0]
    items.append(item)
return(items)

这是个不错的主意,但不幸的是出现了一个类型错误。项目[url]=http://en.wikipedia.org +title.xpatha//@href.extract TypeError:无法连接'str'和'list'对象存在一个错误,您需要执行以下操作,item[url]=+title.xpatha/@href.extract[0]哦,对不起。那是我的错误。它应该是xpath而不是select。select方法已弃用,无法使用。