我正在使用名为this的Python库从Wikipedia(特别是Scrapy)抓取一个网页。这是原始代码:
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"钥匙都是相关链接。 (即:{"url": ["/wiki/9_Full_Moons"], "title": ["9 Full Moons"]}
)。
我需要 http://en.wikipedia.org/wiki/9_Full_Moons ,而不是 / wiki / 9_Full_Moons 。所以我修改了上面提到的代码,从urlparse库中导入 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] 即可。但是,这次我得到的IndexError如下所示:
IndexError:列表索引超出范围
有人可以帮我解释我哪里出错吗?
答案 0 :(得分: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)
答案 1 :(得分:0)
在第一次使用相对链接的代码迭代中,您使用了xpath
方法:item["url"] = title.xpath("a/@href").extract()
返回的对象是(我假设)一个字符串列表,因此索引它是有效的。
在新的迭代中,您使用了select
方法:url = title.select("a/@href").extract()
然后您将返回的对象视为可迭代的url[0]
。检查select
方法返回的内容,也许它是一个列表,如上例所示。
P.S。:IPython是你的朋友。
答案 2 :(得分:0)
因此,在将代码镜像到文档 here 中给出的示例之后,我能够让代码工作:
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)
如果有人需要进一步澄清项类的工作原理, the documentation is here 。
此外,尽管代码有效,但它不会将标题与其各自的链接配对。所以它会给你
TITLE,TITLE,TITLE,LINK,LINK,LINK
而不是
TITLE,LINK,TITLE,LINK,TITLE,LINK
(后者可能是更理想的结果) - 但这是另一个问题。如果有人提出的解决方案比我的解决方案更好,我会非常乐意听取你的答案!谢谢。
答案 3 :(得分:-1)
为了更好地澄清,我将修改上面的代码,
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)