Sto provando a programmare un crawl spider per eseguire la scansione dei feed RSS di un sito Web e quindi analizzare i meta tag dell'articolo.Come utilizzare correttamente le regole, restrict_xpaths per eseguire la scansione e analizzare gli URL con scrapy?
La prima pagina RSS è una pagina che visualizza le categorie RSS. Sono riuscito a estrarre il link perché il tag è in un tag. Ecco come si presenta:
<tr>
<td class="xmlLink">
<a href="http://feeds.example.com/subject1">subject1</a>
</td>
</tr>
<tr>
<td class="xmlLink">
<a href="http://feeds.example.com/subject2">subject2</a>
</td>
</tr>
Una volta cliccato quel link che ti porta i gli articoli per quella categoria RSS che assomiglia a questo:
<li class="regularitem">
<h4 class="itemtitle">
<a href="http://example.com/article1">article1</a>
</h4>
</li>
<li class="regularitem">
<h4 class="itemtitle">
<a href="http://example.com/article2">article2</a>
</h4>
</li>
Come si può vedere che posso ottenere il legame con XPath di nuovo se uso il tag voglio che il mio crawler vada al link all'interno di quel tag e analizzi i metatag per me.
Ecco il mio codice cingolato:
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.selector import HtmlXPathSelector
from tutorial.items import exampleItem
class MetaCrawl(CrawlSpider):
name = 'metaspider'
start_urls = ['http://example.com/tools/rss'] # urls from which the spider will start crawling
rules = [Rule(SgmlLinkExtractor(restrict_xpaths=('//td[@class="xmlLink"]')), follow=True),
Rule(SgmlLinkExtractor(restrict_xpaths=('//h4[@class="itemtitle"]')), callback='parse_articles')]
def parse_articles(self, response):
hxs = HtmlXPathSelector(response)
meta = hxs.select('//meta')
items = []
for m in meta:
item = exampleItem()
item['link'] = response.url
item['meta_name'] =m.select('@name').extract()
item['meta_value'] = m.select('@content').extract()
items.append(item)
return items
Tuttavia questo è l'output quando eseguo crawler:
DEBUG: Crawled (200) <GET http://http://feeds.example.com/subject1> (referer: http://example.com/tools/rss)
DEBUG: Crawled (200) <GET http://http://feeds.example.com/subject2> (referer: http://example.com/tools/rss)
che cosa sto facendo male qui? Ho letto e riletto la documentazione più e più volte, ma mi sembra di continuare a trascurare qualcosa. Qualsiasi aiuto sarebbe apprezzato.
MODIFICA: Aggiunto: items.append (articolo). L'avevo dimenticato nel post originale. EDIT:: Ho provato questo come bene e ha portato alla stessa uscita:
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.selector import HtmlXPathSelector
from reuters.items import exampleItem
from scrapy.http import Request
class MetaCrawl(CrawlSpider):
name = 'metaspider'
start_urls = ['http://example.com/tools/rss'] # urls from which the spider will start crawling
rules = [Rule(SgmlLinkExtractor(allow=[r'.*',], restrict_xpaths=('//td[@class="xmlLink"]')), follow=True),
Rule(SgmlLinkExtractor(allow=[r'.*'], restrict_xpaths=('//h4[@class="itemtitle"]')),follow=True),]
def parse(self, response):
hxs = HtmlXPathSelector(response)
meta = hxs.select('//td[@class="xmlLink"]/a/@href')
for m in meta:
yield Request(m.extract(), callback = self.parse_link)
def parse_link(self, response):
hxs = HtmlXPathSelector(response)
meta = hxs.select('//h4[@class="itemtitle"]/a/@href')
for m in meta:
yield Request(m.extract(), callback = self.parse_again)
def parse_again(self, response):
hxs = HtmlXPathSelector(response)
meta = hxs.select('//meta')
items = []
for m in meta:
item = exampleItem()
item['link'] = response.url
item['meta_name'] = m.select('@name').extract()
item['meta_value'] = m.select('@content').extract()
items.append(item)
return items
Ho provato a modificare le regole per essere: Regola (SgmlLinkExtractor (allow = [r '. *'], Restrict_xpaths = ('// td [@ class = "xmlLink"]')), seguire = True), Rule (SgmlLinkExtractor (allow = [r '. *'], Restrict_xpaths = ('// h4 [@ class = "itemtitle"]')), callback = 'parse_articles') Ma ha comunque prodotto lo stesso produzione. – Marc
Ciao Marc: come hai finalmente risolto quel problema? Quando eseguo gli esempi di scrapy tutto va bene e quando la logica applicata al mio progetto sembra che le regole non vengano mai lanciate ... – hugsbrugs
semplicemente ereditare il tuo ragno da 'scrapy.Spider' è in realtà molto più facile. – lhe