文档章节

一个网站的诞生04--抓取一个餐厅的某个月的全部评论

brian_2017
 brian_2017
发布于 2017/01/17 09:42
字数 1614
阅读 2
收藏 0
第一个Spider是抓上海的城市id,顺带抓它的下一级行政区id。

第二个Spider是抓上海的Top一万家餐厅的Shopid。

本文是第三个Spider,根据一个餐厅的Shopid,抓取它在某个月内的全部评论。

三个Spider的累加效果,就是抓取任意一个城市的TopN家餐厅的全部评论。第三个Spider修改一下,还可以做到只抓取某天的评论,只抓取某人的评论,从抓取的角度看就全齐了。

经过前两次的spider热身,这次做个复杂点的。

URLhttp://www.dianping.com/shop/2269717/review_more?pageno=1是一家餐厅点评的首页,pageno=1表示第1页,每条点评有用户id,点评时间。如果点评是在当前年份的,点评时间不写年份,否则有年份。最下方有分页数,它家的全部点评一共24页。

假如要抓取2014年7月的评论,流程是这样的:

1. 2014年7月有31天,也就是说说,要抓取的是日期从2014-0701到2014-0731。

2. 从http://www.dianping.com/shop/2269717/review_more?pageno=1http://www.dianping.com/shop/2269717/review_more?pageno=24,抓取页面。

3. 如果pageno=1,抓取最底下的分页数,保存最大分页数。

3. 抽取点评,如果点评的创建日期没有年份,用当前年份补上。如果点评的创建日期在2014-0701到2014-0731之间就存储点评。如果在当前页面上,遇到一个点评的创建日期早于2014-0701,就不再抓取新的页面,因为下一页的点评都比要抓取的日期早。

4. 如果遇到403错误,暂停十分钟再继续抓,如果遇到404错误,不继续抓取,返回。

Spider的代码如下:

import datetime
import random
import time

from scrapy.spider import BaseSpider
from scrapy.selector import HtmlXPathSelector
from scrapy.http import Request

class ShopreviewSpider(BaseSpider):
    name = "shopreview_spider"
    allowed_domains = ["dianping.com"]
    start_urls = []

    handle_httpstatus_list = [404,403]

    def __init__(self):
        """
        year_mon = '2014-04'
        shopid = '2269717'
        """
        self._shopid = "2269717"
        self._thisyear_int = datetime.date.today().year

        year_g = 2014
        mon_g = 7
        max_day = 31

        self._min_date = datetime.date(year_g, mon_g, 1)
        self._max_date = datetime.date(year_g, mon_g, max_day)
        
        #set start url
        self.pagno = 1
        self.start_urls = ["http://www.dianping.com/shop/%s/review_more?pageno=%s" % (self._shopid,self.pagno)]

    def parse(self, response):
        if response.status == 403:
            time.sleep(10*60)
            yield Request(response.url,callback=self.parse,
                          headers={'Referer':'http://www.baidu.com/s?psid=sdafwewer'+str(1)})
        elif response.status == 404:
            print "\n\nmeet 404, mark shop fetched and return\n\n"
        else:
            hxs = HtmlXPathSelector(response)
            #extract reviews
            xs = hxs.select('//div[@class=\"comment-list\"]/ul/li')
            generate_new_request = True
            if len(xs) == 0:
                print "len(xs) == 0"
                generate_new_request = False
            for x in xs:
                reviewer = x.select('div[@class=\"pic\"]/a/@href').extract()[0].split('/')[-1]
                review = x.select('div[@class=\"content\"]/div[@class=\"comment-txt\"]/div[@class=\"J_brief-cont\"]').extract()[0].strip()
                reviewdate_t = x.select('div[@class=\"content\"]/div[@class=\"misc-info\"]/span[@class=\"time\"]/text()').extract()[0].split()[0]
                reviewdate=""
                if len(reviewdate_t) == 5:
                    reviewdate = ("%s"%(self._thisyear_int))+"-"+reviewdate_t
                else:
                    reviewdate = "20"+reviewdate_t
                rd1,rd2,rd3 = reviewdate.split('-')
                dd = datetime.date(int(rd1), int(rd2), int(rd3))
                if dd < self._min_date:
                    generate_new_request = False
                elif dd >= self._min_date and dd <= self._max_date:
                    print "----------------"
                    print reviewdate
                    print reviewer
                    print review
                else:
                    pass
        
            xs = hxs.select('//a[@class=\"PageLink\"]')
            num_page_link = len(xs)
            max_pages = -1
            if num_page_link > 0:
                max_pages = max( [int(x.select("text()").extract()[0]) for x in xs] )

            if generate_new_request:
                self.pagno += 1
                if num_page_link == 0 or self.pagno > max_pages:
                    pass
                else:
                    new_url = "http://www.dianping.com/shop/%s/review_more?pageno=%s" % (self._shopid, self.pagno)
                    rand_int = random.randint(1,999999)
                    yield Request(new_url, callback=self.parse,
                                  headers={'Referer':'http://www.baidu.com/s?psid=sdafwewer'+str(rand_int)})

这个spider在/tmp/scrapy-test/crawdp/crawdp/spiders/shopreview_spider.py。

在/tmp/srcapy-test/crawdp目录下运行"scrapy crawl shopreview_spder",效果是这样的:

----------------
2014-07-31
1198927
<div class="J_brief-cont">
                        这家店换了一家又一家<br>不知道什么时候才会消停<br>总体来说工作日中午的商务餐生意非常不错<br>没有特别的菜<br>总体感觉还不错
                </div>
----------------
2014-07-29
1942230
<div class="J_brief-cont">
                        给孩子庆祝六一节,住附近酒店,经点评研究发现了这家店,在5点差1分钟的时候要求点下午茶套餐,被接受了!呵呵<br>环境很港式,下午茶不错!
                </div>
----------------
2014-07-29
428660
<div class="J_brief-cont">
                        荷叶饭很不错。铁板鱿鱼也很不错。
                </div>
----------------
2014-07-24
57148861
<div class="J_brief-cont">
                        金桔柠檬甜甜的但是我比较喜欢酸的 很多菜看起来都很好吃 服务态度好 环境简单干净 两个人早茶吃了117
                </div>
----------------
2014-07-20
5186406
<div class="J_brief-cont">
                        是地道的港式餐厅,口味正宗,菜式多样,还经常推陈出新,经常去会有惊喜
                </div>
----------------
2014-07-14
1836211
<div class="J_brief-cont">
                        这家店的分数说实话,以我个人的看法,是偏低了,这种店如果放在我以前住的五毛厂周围,完暴万达广场内的那些难吃的店了,煲仔饭尤其推荐。
                </div>
----------------
2014-07-13
10365
<div class="J_brief-cont">
                        纯粹是 为了到隔壁的虾满堂买小龙虾才来的,隔壁龙虾店5点不到不开业,只得在这家店歇歇脚,点了一份 下午茶套餐,奶茶+鱼蛋肠粉,味道很地道,旁边几桌的 顾客都说广东话应该这家店满正宗的,不好的地方就是一楼好像是吸烟区,坐在里面被动吸二手烟了。
                </div>
----------------
2014-07-08
48406752
<div class="J_brief-cont">
                        炸鲜奶很好吃,各色菜品量很大,晚上去的环境很不错,值得推荐!
                </div>
----------------
2014-07-03
57580045
<div class="J_brief-cont">
                        翔记生蚝考的味道还可以,我和同事有时会去吃吃,环境一般,服务一般,
                </div>
----------------
2014-07-02
14718103
<div class="J_brief-cont">
                        服务员态度绝对点赞。海鲜粥,烧得有点小胡,还算鲜,干贝有点太咸。滑鸡煲,有很多脆脆得藕片,鸡挺嫩。萝卜牛肉煲,萝卜炖得可以。炸鲜奶,挺奇怪得一道菜,为什么甜甜得东西里头会有蒜味?
                </div>
----------------
2014-07-01
36276873
<div class="J_brief-cont">
                        一家港式茶餐厅,看见很多人都直接点一份主食(炒河粉或炒米线之类)当晚饭。大厅挂着很大的电视在播粤语节目,邻桌就是一桌香港人在用餐。<br>很喜欢他家的白灵菇牛肉片,除了有一点点咸之外,白灵菇吃起来很饱满有筋道;招牌猪脚味道不错但只有五六个,还是略咸;有一道蔬菜凉菜的,不好吃,紫甘蓝都切好大片,而且芝麻酱不多,摆盘和以前吃的都不一样,端上来很大一盆其实并没有那么多,里面用料也一般;主食是排骨河粉,无功无过。<br>服务员态度都还不错。
                </div>

Scrapy在处理<br>元素的时候,会有点小问题,所以点评的原文不得以要保留了<div>和<br>。

© 著作权归作者所有

brian_2017
粉丝 3
博文 61
码字总数 145216
作品 0
私信 提问
NetCloud——一个网易云音乐评论抓取和分析的Python库

在17的四月份,我曾经写了一篇关于网易云音乐爬虫的文章,还写了一篇关于评论数据可视化的文章。在这大半年的时间里,有时会有一些朋友给我发私信询问一些关于代码方面的问题。所以我最近抽空...

lyrichu
2018/02/04
0
0
selenium+firefox模拟下滑抓取新浪新闻

# -- coding: utf-8 --"""Created on Thu Feb 1 16:00:57 2018 @author: Administrator""" import timefrom selenium import webdriverfrom selenium.webdriver.firefox.firefox_binary impo......

castinga3t
2018/02/07
0
0
使用 BeautifulSoup 和 Selenium 进行网页爬取

概述 HTML几乎是平铺直叙的。CSS是一个伟大的进步,它清晰地区分了页面的结构和外观。JavaScript添加一些魅力。道理上讲是这样的。现实世界还是有点不一样。 在本教程中,您将了解在浏览器中...

开源中国首席屌炸天
2018/08/28
1K
2
您的披萨在路上,外卖公司 Zume 让机器人制作配送员烘焙

近日,硅谷披萨外卖公司 Zume 宣布与餐饮设备供应商 Welbilt 合作。此后, Zume 的餐车将向更多餐饮公司开放,变成一个移动食堂,期望能“颠覆”美国 430 亿美元的外卖市场。 比起披萨外卖店...

36kr
2018/04/27
0
0
安吉江南天池@清明节假期

安吉江南天池@清明节假期 一个故事@MySQL DBA2017-04-1628 阅读 今后打算充分利用各种假期把杭州周边(驾车3小时以内)都转转,这次清明节假期选了安吉江南天池。 导航显示路程84公里,但是却需...

一个故事@MySQL DBA
2017/04/16
0
0

没有更多内容

加载失败,请刷新页面

加载更多

python数据结构

1、字符串及其方法(案例来自Python-100-Days) def main(): str1 = 'hello, world!' # 通过len函数计算字符串的长度 print(len(str1)) # 13 # 获得字符串首字母大写的...

huijue
5分钟前
0
0
OSChina 周日乱弹 —— 我,小小编辑,食人族酋长

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @宇辰OSC :分享娃娃的单曲《飘洋过海来看你》: #今日歌曲推荐# 《飘洋过海来看你》- 娃娃 手机党少年们想听歌,请使劲儿戳(这里) @宇辰OSC...

小小编辑
今天
735
10
MongoDB系列-- SpringBoot 中对 MongoDB 的 基本操作

SpringBoot 中对 MongoDB 的 基本操作 Database 库的创建 首先 在MongoDB 操作客户端 Robo 3T 中 创建数据库: 增加用户User: 创建 Collections 集合(类似mysql 中的 表): 后面我们大部分都...

TcWong
今天
40
0
spring cloud

一、从面试题入手 1.1、什么事微服务 1.2、微服务之间如何独立通讯的 1.3、springCloud和Dubbo有哪些区别 1.通信机制:DUbbo基于RPC远程过程调用;微服务cloud基于http restFUL API 1.4、spr...

榴莲黑芝麻糊
今天
26
0
Executor线程池原理与源码解读

线程池为线程生命周期的开销和资源不足问题提供了解决方 案。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。 线程实现方式 Thread、Runnable、Callable //实现Runnable接口的...

小强的进阶之路
昨天
79
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部