我正在尝试用scrapy制作一个专门针对的网络爬虫,它会返回我的结果对象。我被卡住了,可能正在完全倒退。
更具体地说,对于TheScienceForum.com上的每个子论坛(数学、物理等),我想获取每个子论坛中所有主题的标题,并最终得到一个具有论坛名称的对象和论坛中所有主题的标题列表。
最终目标是对主题标题进行文本分析,以确定与每个论坛相关的最常见术语/行话。最终我也想对线程本身进行分析。
我有一个类 Item 定义如下:
from scrapy.item import Item, Field
class ProjectItem(Item):
name = Field() #the forum name
titles = Field() #the titles
我可能会误解项目的工作原理,但我希望每个子论坛都有一个项目,该子论坛的所有主题标题都在同一项目的列表中。
我写的爬虫看起来像这样,但没有按预期运行:
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.selector import HtmlXPathSelector
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from individualProject.items import ProjectItem
class TheScienceForum(CrawlSpider):
name = "TheScienceForum.com"
allowed_domains = ["theScienceForum.com"]
start_urls = ["http://www.thescienceforum.com"]
rules = [Rule(SgmlLinkExtractor(restrict_xpaths=['//h2[@class="forumtitle"]/a']), 'parse_one'),Rule(SgmlLinkExtractor(restrict_xpaths=['//div[@class="threadpagenav"]']), 'parse_two')]
def parse_one(self, response):
Sel = HtmlXPathSelector(response)
forumNames = Sel.select('//h2[@class="forumtitle"]/a/text()').extract()
items = []
for forumName in forumNames:
item = projectItem()
item['name'] = forumName
items.append(item)
yield items
def parse_two(self, response):
Sel = HtmlXPathSelector(response)
threadNames = Sel.select('////h3[@class="threadtitle"]/a/text()').extract()
for item in items:
for title in titles:
if Sel.select('//h1/span[@class="forumtitle"]/text()').extract()==item.name:
item['titles'] += Sel.select('//h3[@class="threadtitle"]/a/text()').extract()
return items
这个想法是从所有子论坛名称所在的站点的主页开始。第一条规则只允许链接到第一个子论坛页面和与之关联的解析函数,它意味着为每个子论坛创建一个项目,在论坛名称中为“名称”属性添加子项。
对于以下请求,使用第二条规则,蜘蛛仅限于导航包含子论坛的所有线程(分页链接)的页面。第二个解析方法旨在将线程标题添加到与当前子论坛名称对应的项目(在第一个解析方法中创建)(Sel.select('//h1/span[@class="forumtitle"]/ text()').extract())
蜘蛛正在爬到所有主要的论坛页面,但是对于每个页面,我都会收到以下错误:
2013-11-01 13:05:37-0400 [TheScienceForum.com] ERROR: Spider must return Request, BaseItem or None, got 'list' in <GET http://www.thescienceforum.com/mathematics/>
任何帮助或建议将不胜感激。谢谢!