想要达成的功能大致如下:
没有报错,书评的一级信息全部写入,但是二级书评没有写入,代码如下:
item代码如下
# -*- coding: utf-8 -*-
import scrapy
class YswItem(scrapy.Item):
#发帖时间
time = scrapy.Field()
#获得赞同数量
agree = scrapy.Field()
#二级评论数量
sec_num = scrapy.Field()
#一级评论内容
fir_text = scrapy.Field()
class YswItems(scrapy.Item):
#发帖时间
time = scrapy.Field()
#获得赞同数量
agree = scrapy.Field()
#二级评论数量
sec_num = scrapy.Field()
#一级评论内容
fir_text = scrapy.Field()
#二级评论内容
sec_text = scrapy.Field()
————————————————————————————
spider.shuping类代码如下:
# -*- coding: utf-8 -*-
import scrapy
from scrapy.http import Request
from ysw.items import YswItem
from ysw.spiders.shuping_two import Shuping_twoSpiser
class ShupingSpider(scrapy.Spider):
name = 'shuping'
#allowed_domains = ['www.yousuu.com']
start_urls = ['http://www.yousuu.com/book/124600']
#此方法解析评论第一页的一级书评
def parse(self, response):
sp_two = Shuping_twoSpiser()
#遍历每个一级书评,获得信息
for r in response.xpath('//*[@id="content"]/div'):
item = YswItem()
#发帖时间
item['time'] = r.xpath('string(./div/div/div[1]/div/span[2])').extract_first().strip()
#获得赞同数
agree = r.xpath('string(./div/div/div[2]/button[1]/span)').extract_first().strip()
if agree:
item['agree'] = agree
else:
item['agree'] = '0'
#一级书评内容
item['fir_text'] = r.xpath('string(./div/div/p)').extract_first().replace('\r\n', '').replace(' ', '')
#二级评论数:
sec_num = r.xpath('string(./div/div/div[2]/button[2]/span)').extract_first().strip()
if sec_num:
item['sec_num'] = sec_num
#获取二级评论url的组成部分cid
cid = r.xpath('./@cid').extract_first().strip()
#补全二级评论第一页的url
sec_text_url = "http://www.yousuu.com/ajax/getonecomment?render=true&cid={}".format(cid)
#将每一个一级书评下的所有二级书评的获取都交给sp_two.parse
sec_text_list = []
yield Request(sec_text_url, meta={'sec_text_list':sec_text_list, 'item':item}, callback=sp_two.parse)
else:
item['sec_num'] = '0'
yield item
return print('一级书评第一页!')
————————————————————————
spider.shuping_two类代码如下:
# -*- coding: utf-8 -*-
import scrapy
from scrapy.http import Request
from ysw.items import YswItems
import re
import json
from scrapy.selector import Selector
#解析二级书评
class Shuping_twoSpiser(scrapy.Spider):
name = 'shuping_two'
#allowed_domains = ['www.yousuu.com']
#start_urls = []
def parse(self, response):
items = YswItems()
#json格式转为python结构数据
jsobj = json.loads(response.body)
#从字典中提取html的值,也就是二级评论的html格式文本
html = jsobj['html']
#获得二级书评第一页的所有二级书评内容,放在列表result中,迭代这个parse方法时,依次是第2,3,页等等
result = Selector(text=html).xpath('//p/text()').extract()
#获得上一个Request传递过来的参数, 第一次是一个空列表
sec_text_list = response.meta['sec_text_list']
#获得shuping.parse()传来的item
item = response.meta['item']
'''每一页的二级评论内容放在一个列表result中,这个列表又放在列表sec_text_list中
二级书评每一页的第一个书评都是它的一级书评内容,所以从每一页新的二级书评从第二个算起'''
sec_text_list.append(result[1:])
#判断二级评论是否还有下一页
nextpage = Selector(text=html).xpath('//a[text()="更多回复"]/@onclick').extract_first()
if nextpage:
#获得下一页的cid
cid = re.search(r"(.*?)'(.*?)',(.*)", nextpage).group(2)
#获取下一页的t
t = re.search("(.*),(.*?)\)", nextpage).group(2)
#组装二级评论下一页的url
next_page_url = "http://www.yousuu.com/ajax/getcommentreply?cid={}&t={}&render=true".format(cid, t)
#print('next_page_url')
#迭代这个方法继续获得下一页的二级评论内容
yield Request(next_page_url, meta={'sec_text_list':sec_text_list, 'item':item}, callback=self.parse)
else:
items['sec_text'] = sec_text_list
items['time'] = item['time']
items['agree'] = item['agree']
items['sec_num'] = item['sec_num']
items['fir_text'] = item['fir_text']
print('已获取此一级书评的全部二级书评!')
yield items
——————————————————————————
pipeline代码如下:
# -*- coding: utf-8 -*-
import os
class YswPipeline(object):
def process_item(self, item, spider):
base_dir = os.getcwd()
file_name = base_dir + '/SP.txt'
with open(file_name, 'a', encoding='utf-8') as f:
if spider.name=='shuping':
f.write('时间:' + item['time'] + '\n'
'赞同数:' + item['agree'] + '\n'
'二级评论数量:' + item['sec_num'] + '\n'
'一级评论内容:' + item['fir_text'] + '\n\n'
)
elif spider.name=='shuping_two':
f.write('时间:' + item['time'] + '\n'
'赞同数:' + item['agree'] + '\n'
'二级评论数量:' + item['sec_num'] + '\n'
'一级评论内容:' + item['fir_text'] + '\n'
'二级评论内容:' + '\n'.join(item['sec_text']) + '\n\n'
)
return item
写入结果如下:
请知道怎么处理的前辈指点迷津,卡在这一天了,真的很虐心。感谢!感谢!
为什么要弄两个spider呢?你完完全全可以在第一个spider下再写一个parse_shuping_two啊.
对你的代码稍作了修改,可以达到你的要求(别忘了在settings.py中加上
ITEM_PIPELINES = {'ysw.pipelines.YswPipeline': 300}
以激活pipeline):spiders/shuping.py
pipelines.py