2015-01-16 8 views
8
class AljazeeraSpider(XMLFeedSpider): 
    name = "aljazeera" 
    allowed_domains = ["aljazeera.com"] 
    start_urls = [ 
     'http://www.aljazeera.com/', 
    ] 

    def parse(self, response): 
     hxs = HtmlXPathSelector(response) # The xPath selector 
     titles = hxs.select('//div[contains(@class,"SkyScrapperBoxes")]/div[contains(@class,"skyscLines")]') 
     if not titles: 
      MailNotify().send_mail("Aljazeera", "Scraper Report") 

     items = [] 
     for titles in titles: 
      item = NewsItem() 
      item['title'] = escape(''.join(titles.select('a/text()').extract())) 
      item['link'] = "http://www.aljazeera.com" + escape(''.join(titles.select('a/@href').extract())) 
      item['description'] = '' 
      item = Request(item['link'], meta={'item': item}, callback=self.parse_detail) 
      items.append(item) 

     return items 

    def parse_detail(self, response): 
     item = response.meta['item'] 
     sel = HtmlXPathSelector(response) 
     detail = sel.select('//td[@class = "DetailedSummary"]') 
     item['details'] = remove_html_tags(escape(''.join(detail.select('p').extract()))) 
     item['location'] = '' 
     published_date = sel.select('//span[@id = "ctl00_cphBody_lblDate"]') 
     item['published_date'] = escape(''.join(published_date.select('text()').extract())) 

     return item 

Ich arbeite derzeit an Scrapy, um die Website zu crawlen. Ich habe etwas über Unittest in Python. Aber, wie kann ich den unittest schreiben, um zu überprüfen, dass Verbindung funktioniert, und geben item['location'], item['details'] den Wert zurück oder nicht? Ich habe Scrapy-Vertrag gelernt, kann aber nichts verstehen. Also, wie kann ich in diesem Fall den Unitest schreiben?Wie kann ich beginnen, Komponententest im Web Scrapy mit Python zu schreiben?

Antwort

12

Wenn wir speziell darüber sprechen, wie die Spider (nicht Pipelines oder Loader) getestet werden sollen, dann haben wir eine "falsche Antwort" aus einer lokalen HTML-Datei erhalten. Beispielcode:

import os 
from scrapy.http import Request, TextResponse 

def fake_response(file_name=None, url=None): 
    """Create a Scrapy fake HTTP response from a HTML file""" 
    if not url: 
     url = 'http://www.example.com' 

    request = Request(url=url) 
    if file_name: 
     if not file_name[0] == '/': 
      responses_dir = os.path.dirname(os.path.realpath(__file__)) 
      file_path = os.path.join(responses_dir, file_name) 
     else: 
      file_path = file_name 

     file_content = open(file_path, 'r').read() 
    else: 
     file_content = '' 

    response = TextResponse(url=url, request=request, body=file_content, 
          encoding='utf-8') 
    return response 

Dann in Ihrer TestCase Klasse, rufen Sie die fake_response() Funktion und füttern die Antwort auf die parse() Rückruf:

from unittest.case import TestCase 

class MyTestCase(TestCase): 
    def setUp(self): 
     self.spider = MySpider() 

    def test_parse(self): 
     response = fake_response('input.html') 
     item = self.spider.parse(response) 
     self.assertEqual(item['title'], 'My Title') 
     # ... 

Abgesehen davon, sollten Sie auf jeden Fall beginnen Item Loaders mit Mit Eingabe- und Ausgabeprozessoren - dies würde helfen, eine bessere Modularität und somit Isolation zu erreichen - würde Spider nur Iteminstanzen liefern, Datenvorbereitung und -modifikation würden innerhalb der Loaded verkapselt werden r, die du separat testen würdest.