使用Scrapy解析网站,跟随下一页并写入XML
我的脚本在我把一段代码注释掉时运行得很好:return items。
这是我的代码,我把链接改成了http://example.com,因为看起来其他人也是这样做的,可能是为了避免抓取数据的法律问题。
class Vfood(CrawlSpider):
name = "example.com"
allowed_domains = [ "example.com" ]
start_urls = [
"http://www.example.com/TV_Shows/Show/Episodes"
]
rules = (
Rule(SgmlLinkExtractor(allow=('example\.com', 'page='), restrict_xpaths = '//div[@class="paginator"]/
span[@id="next"]'), callback='parse'),
)
def parse(self, response):
hxs = HtmlXPathSelector(response)
items = []
countries = hxs.select('//div[@class="index-content"]')
tmpNextPage = hxs.select('//div[@class="paginator"]/span[@id="next"]/a/@href').extract()
for country in countries:
item = FoodItem()
countryName = country.select('.//h3/text()').extract()
item['country'] = countryName
print "Country Name: ", countryName
shows = country.select('.//div[@class="content1"]')
for show in shows.select('.//div'):
showLink = (show.select('.//h4/a/@href').extract()).pop()
showLocation = show.select('.//h4/a/text()').extract()
showText = show.select('.//p/text()').extract()
item['showURL'] = "http://www.travelchannel.com"+str(showLink)
item['showcity'] = showLocation
item['showtext'] = showText
item['showtext'] = showText
print "\t", showLink
print "\t", showLocation
print "\t", showText
print "\n"
items.append(item)
**#return items**
for NextPageLink in tmpNextPage:
m = re.search("Location", NextPageLink)
if m:
NextPage = NextPageLink
print "Next Page: ", NextPage
yield Request("http://www.example.com/"+NextPage, callback = self.parse)
else:
NextPage = 'None'
SPIDER = food()
如果我把 #return items 这行取消注释,我就会遇到以下错误:
yield Request("http://www.example.com/"+NextPage, callback = self.parse)
SyntaxError: 'return' with argument inside generator
由于我保留了注释,我无法以XML格式收集数据,但通过打印出来的结果,我确实在屏幕上看到了我应该看到的所有内容。
我用来获取XML的命令是:
scrapy crawl example.com --set FEED_URI=food.xml --set FEED_FORMAT=xml
当我取消注释return items这一行时,我可以创建XML文件,但脚本就停止了,无法继续跟踪链接。
3 个回答
CrawlSpider 类使用了一个叫做 Parse 的方法,所以你应该给你自己写的解析方法起个不同的名字,比如叫 parse_item()。想了解更多,可以查看“爬虫规则”这个链接 http://doc.scrapy.org/topics/spiders.html#scrapy.spider.BaseSpider。
这个链接能回答你的问题吗?:http://www.answermysearches.com/python-fixing-syntaxerror-return-with-argument-inside-generator/354/
这个错误的意思是,当你在一个函数里使用了 yield 让它变成一个生成器时,你只能用没有参数的 return。
我还建议使用像这样的项目加载器:
def parse(self, response):
l = XPathItemLoader(item=Product(), response=response)
l.add_xpath('name', '//div[@class="product_name"]')
l.add_xpath('name', '//div[@class="product_title"]')
l.add_xpath('price', '//p[@id="price"]')
l.add_xpath('stock', '//p[@id="stock"]')
l.add_value('last_updated', 'today') # you can also use literal values
return l.load_item()
你现在是在返回一个物品的列表(可能放错地方了),然后在同一个函数里又用到了 yield 来生成请求。在 Python 里,不能这样混用 yield 和 return。
你要么把所有东西都加到一个列表里,然后在解析方法的最后返回这个列表,要么在所有地方都使用 yield。我建议把 items.append(item)
替换成 yield item
,然后把所有关于物品列表的引用都去掉。