了解我想要实现的目标;我试图为我的网站构建一个文章刮刀,我想要遍历我所有网页上的链接,提取元数据以确定它是否是一篇文章,如果是,将URL +关联数据存储在数据库(Mongo)中。
我找到了python-goose article extractor,我想用它来检索整篇文章。但我认为我在那里领先于自己。
以下代码是我的尝试,它有效,但不会迭代。我假设我需要一个for循环,但我不知道如何去做。有人能指出我正确的方向吗?
from scrapy import Spider
from scrapy.selector import Selector
from scrapy.http import Request
from scrapy.linkextractors import LinkExtractor
from harland.items import *
class StuffSpider(Spider):
name = "stuff"
allowed_domains = ["stuff.co.nz"]
start_urls = [
"http://www.stuff.co.nz/business/industries/70284251/brazil-a-surprise-growth-market-for-moa"
]
rules = (Rule(sle(allow=["/business/"]), callback='parse_item', follow=True)
def parse(self, response):
article = Selector(response)
page = Selector(response).xpath('/html/head/meta[9]')
page_type = page.xpath('//meta[@property="og:type"]/@content').extract()
if "article" in page_type:
item = StuffItem()
item['url'] = page.xpath('//meta[@property="og:url"]/@content')
item['title'] = page.xpath('//meta[@property="og:title"]/@content')
item['description'] = page.xpath('//meta[@property="og:description"]/@content')
yield item
yield Request(item['url'], callback=self.parse)
答案 0 :(得分:1)
如果你不使用循环或任何Rule
你的代码不会迭代。
由于您的example.com
域名,很难说最好的文章是什么(目前我还没有把Goose带入答案中)。
您可以设置Rule
,其中提取并跟踪网站上的网址。您可以使用此方法遍历站点并访问所有URL(您也可以定义限制)并执行特定的爬网行为。有关详细信息,请参阅the docs。
第二种方法是自己提取网址,yield
将其作为新的Request
提取,让Scrapy知道要访问的网站。这会产生更多的编码开销,但会减少网络流量,因为您可以确定要加载哪些站点。要详细了解Request
,请查看the docs。
如果从正在解析的站点中提取URL或子树列表,请使用循环(大多数情况下for
可以)进行迭代。
根据评论和修改进行更新
您的提取无法在parse
方法中使用,因为您尝试将Selector
个对象设置为Field
值,然后使用Selector
之一作为Request
的网址{1}}。您应extract
来自这些选择器的内容。
您的Rule
定义了callback='parse_item'
。目前我没有看到parse_item
函数的实现。因此,即使Rule
命中,因为缺少callback
而无法获得结果。
因此,要使用parse
函数解决问题,请使用以下内容填充item
:
item['url'] = page.xpath('//meta[@property="og:url"]/@content').extract()[0]
item['title'] = page.xpath('//meta[@property="og:title"]/@content').extract()
item['description'] = page.xpath('//meta[@property="og:description"]/@content').extract()
这应该使您的Request
能够启动并再次调用parse
方法 - 这会导致一些重复,Scrapy会通过DEBUG
消息告诉您。< / p>