到目前为止只是读取一个商品的评论,最终是需要获取所有某个商品的评论。
计划使用2个爬虫完成这个功能
a.第一个爬虫获取商品所有列表
b.修改上个博客提到的如何获取一个商品的评论,增加获取所有商品的评论
1.如何定位html页面中的唯一元素
前2次的探索有一个问题没解决,怎么定位html页面中的唯一元素,总结了一个查看方法,
以定位搜索页面中列出所有商品为例:京东的搜索页面url:http://search.jd.com/Search?keyword=eland&enc=utf-8&page=1
a.使用firefox的工具Inspect Element定位想要的内容
b.复制唯一的元素编码
通过scrapy 检查探索一下:
scrapy shell --nolog
fetch('http://search.jd.com/Search?keyword=eland&enc=utf-8&page=1')
--获取页面数
print response.css('.fp-text > i:nth-child(3)').extract_first()
print response.css('.fp-text > i:nth-child(3)').xpath('./text()').extract_first()
--获取sku的id
comment0 = response.css('#J_goodsList')
print comment0.css('li.gl-item::attr(data-sku)').extract()
2.使用默认模板创建 spider
--获取商品列表
scrapy genspider jdcomment02spider club.jd.com
--所有商品
scrapy genspider jdcomment03spider club.jd.com
scrapy list --查看一下
3.获取列出所有商品列表
目前获取有几页商品,还未解决,先人工看了确认。
# -*- coding: utf-8 -*-
import scrapy
from tutorial.items import DmozItem
srat_url_shrt = "http://search.jd.com/Search?keyword=eland&enc=utf-8&page="
#符合结果的商品一共有几页,目前先人工实现
commentrange = 37
class Jdcomment02spiderSpider(scrapy.Spider):
name = "jdcomment02spider"
allowed_domains = ["club.jd.com"]
start_urls = []
for i in range(commentrange):
s_url = start_url_shrt + str(i + 1)
start_urls.append(s_url)
def parse(self, response):
items = []
goodslist= response.css('#J_goodsList')
comments = goodslist.css('li.gl-item::attr(data-sku)').extract()
for comment in comments:
item = JDItems()
item['prodid'] = comment
items.append(item)
return items
----------------------------
导出结果到itemlists.csv
echo '' > itemlists.csv
scrapy crawl jdcomment02spider -o itemlists.csv -t csv
4.获取所有商品的评论
在jdcomment01spider的基础上修改一下内容
a.读取的itemlists.csv 列出的所有商品,作为start_url列表
b.修改导出的内容格式,将评论的列输出到一行
商品、页序号、页中编号、用户名称、购买日期、颜色、尺码、评论
修改items.py增加
class JDComments(scrapy.Item):
prodid = scrapy.Field()
pageid = scrapy.Field()
pageindex = scrapy.Field()
userid = scrapy.Field()
buyday = scrapy.Field()
color = scrapy.Field()
size = scrapy.Field()
desc = scrapy.Field()
修改jdcomment02spider.py
# -*- coding: utf-8 -*-
import scrapy
from tutorial.items import JDComments
import urllib2
import math
import json
import csv
commentpeypage = 30
class Jdcomment01spiderSpider(scrapy.Spider):
name = "jdcomment03spider"
allowed_domains = ["club.jd.com"]
start_urls = []
csvfile = file('itemlists.csv', 'rb')
reader = csv.reader(csvfile)
next(reader)
for line in reader:
itemnum = line[0]
print '--------------------parse item:',itemnum
itemsummaryurl='http://club.jd.com/ProductPageService.aspx?method=GetCommentSummaryBySkuId&referenceId=' + itemnum
try:
itemsummaryresponse = urllib2.urlopen(itemsummaryurl)
itemsummaryjson_dict = json.loads(itemsummaryresponse.read())
commentrange = int(math.ceil(itemsummaryjson_dict.get('CommentCount'))/commentpeypage)
for i in range(commentrange):
s_url = "http://club.jd.com/review/" + itemnum + "-" + str(i) + "-0.html"
start_urls.append(s_url)
except Exception,e:
print "Error retrieving data:", e
csvfile.close()
def parse(self, response):
items = []
for i in range(0, commentpeypage ):
divs = response.xpath('//div[@id="' + str(i) + '"]')
item = JDComments()
item['prodid'] = response.url[28:response.url.index('-')]
item['pageid'] = response.url[response.url.index('-') + 1:].replace('.html','')
item['pageindex'] = i
item['userid'] = divs.xpath('.//div[@class="item"]//div[@class="user"]//div[@class="u-name"]/text()').extract_first().replace("\r\n", '')
for zz in divs.xpath('.//dl'):
datatype = zz.xpath('.//dt/text()').extract_first().replace("\r\n", '')
data = zz.xpath('.//dd/text()').extract_first().replace("\r\n", '')
if datatype == u'\u8d2d\u4e70\u65e5\u671f\uff1a':
item['buyday'] = data
if datatype == u'\u989c\u3000\u3000\u8272\uff1a':
item['color'] = data
if datatype == u'\u5c3a\u3000\u3000\u7801\uff1a':
item['size'] = data
if datatype == u'\u5fc3\u3000\u3000\u5f97\uff1a':
item['desc'] = data
items.append(item)
return items
5.检查结果
echo '' > itemlists.csv
scrapy crawl jdcomment02spider -o itemlists.csv -t csv
echo '' > itemcomments.csv
scrapy crawl jdcomment03spider -o itemcomments.csv -t csv --nolog
6.下一步修改方向
start_url如何根据返回结果读取下一层的url,需要使用callback函数。