第一次爬取:
https://zh.airbnb.com/rooms/15473761?guests=1&adults=1&children=0&infants=0&location=%E6%9D%AD%E5%B7%9E&s=HHVshTGq
打开上面的网址,在网页代码中可以看到有评论。想要爬取这一页的评论是非常简单的,以下是代码:
# coding:utf-8
import json
import requests
from bs4 import BeautifulSoup
if __name__=="__main__":
main_page='https://zh.airbnb.com/rooms/15473761?guests=1&adults=1&children=0&infants=0&location=%E6%9D%AD%E5%B7%9E&s=HHVshTGq'
res = requests.get(main_page)
soup = BeautifulSoup(res.text, 'html.parser')
comments=[]
for comment in soup.select('.text_5mbkop-o_O-size_reduced_1oti1ib-o_O-weight_light_1nmzz2x'):
comments.append(comment.text)
print(json.dumps(comments).decode("unicode-escape"))
以下的结果:
["很开心的一次住宿体验,有幸尝到了言姐姐做的饼干,很好吃哟,在临走的时候奶奶也很热心,墙上还有附近餐馆的地址很贴心,天台很好看,虽然下雨天但还是不影响看外景的,希望下次还有机会去言姐姐家", "本来以为阁楼会比较小,但其实特别显大,住着感觉很舒服,房子很漂亮很安静,离西湖很近,言和叔叔阿姨人都超级好,感觉特别亲切,对啦,还买了很棒的茶叶,下次有机会一定还要和爸爸妈妈来一次,还要住在言家里~~", "很适合度假的房子,环境优美。言的家人都很友好,住着很轻松的感觉,房子地理位置咋说呢,走出去就是西湖的一部分,好吃的餐厅像弄堂里,绿茶餐厅都很近。早餐很好吃。不过公交车晚上很早就停了,如果喜欢夜生活的小伙伴,回来就要打的啦。去各个景区都挺方便的。离市区还是有段距离的,公交车晚上停的早,如果喜欢热闹地方的小伙伴建议就住市区里吧。西湖的音乐喷泉有点好看,大家可以去看。言家的房子,很适合心灵的休息,窗外都是美景,阳台超棒,可以泡泡言姐准备的茶,那个叫生活啊!", "特别好 有种家的感觉 爸爸妈妈奶奶都特别亲切,很遗憾没见到言,不过整间房子里都充满了温暖,下次来杭州还住您家", "在临走前的晚上看到了言姐姐 感觉人超nice 言的爸爸妈妈还有奶奶也特别热情好客 感谢他们这几天的照顾~住的地方环境真的太好了 早起在阳台上 听着风铃声和鸟叫声 简直太惬意了!傍晚的时候在林间道上骑单车感觉也超棒!希望下次还有机会来杭州来茅家埠住言的房子~", "特别喜欢她家的旋转楼梯和阳台,还有个小院子", "相比一般的旅店多了回家的感觉,很温馨!大露台是最爱_这次没看到星星,下次再来!"]
结果很成功,但是它只能爬取当页的信息,当点击第二页时,评论内容刷新了,但是网页的网址没有变化!这就很难办了。
第二次爬取:
还是刚才的那的网址,滑动到评论的末尾,点击network,当我们点击2时,发现在众多的messages和events中还存在一个另类的:
reviews?key=d306zoyjsyarp7ifhu67rjxn52tv0t20¤cy=CNY&locale=zh&listing_id=15515107&role=guest&_format=for_p3&_limit=7&_offset=7&_order=ranked_languages_countries
双击,会弹出一个新的网页:
很好!这就是包含我们所需要的评论的json!
接下来,我进入不同的房源进行相同的操作,以下是这些评论的网址,其中前两个是同一个房源的不同评论页面,后两个分别来自两个不同的房源:
https://zh.airbnb.com/api/v2/reviews?key=d306zoyjsyarp7ifhu67rjxn52tv0t20¤cy=CNY&locale=zh&listing_id=15473761&role=guest&_format=for_p3&_limit=7&_offset=21&_order=ranked_languages_countries
https://zh.airbnb.com/api/v2/reviews?key=d306zoyjsyarp7ifhu67rjxn52tv0t20¤cy=CNY&locale=zh&listing_id=15473761&role=guest&_format=for_p3&_limit=7&_offset=14&_order=ranked_languages_countries
https://zh.airbnb.com/api/v2/reviews?key=d306zoyjsyarp7ifhu67rjxn52tv0t20¤cy=CNY&locale=zh&listing_id=15515107&role=guest&_format=for_p3&_limit=7&_offset=7&_order=ranked_languages_countries
https://zh.airbnb.com/api/v2/reviews?key=d306zoyjsyarp7ifhu67rjxn52tv0t20¤cy=CNY&locale=zh&listing_id=15709444&role=guest&_format=for_p3&_limit=7&_offset=7&_order=ranked_languages_countries
如果你看得够仔细,相信到这里你一定会笑了:这四个网址拥有相同的格式,区别在于locale=zh&listing_id
以及_limit=7&_offset=7
,那我们接下来的策略就是:寻找每一个房源的id,这很容易,其实已经包含在了我在上文给出的url里面了。其次是将_limit=
设置为10,将_offset=
设置为0,从每一个json中提取评论。如果已知评论总数为101,每页可以显示10个评论,那么需要爬11次。
home = [['12160895', 104], ['15516056', 59], ['15807919', 34], ['15473761', 101], ['7816441', 75], ['8133141', 98],
['6563956', 149], ['11505129', 96], ['13131814', 35], ['15225079', 34], ['15941869', 42], ['10301999', 58],
['8435107', 67], ['9362909', 79], ['16473681', 26], ['18236040', 3], ['15709444', 49], ['6562686', 39],
['16591080', 39], ['18499416', 0]]
以上是我整理好的TOP20房源的id以及评论,最后一个是新房源,所以评论为0;
以下是python代码:
# coding:utf-8
import json
import urllib2
import sys
reload(sys)
sys.setdefaultencoding( "utf-8" )
def get_comment(url):
user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36' # 将user_agent写入头信息
headers = {'User-Agent': user_agent}#使用headers伪装成浏览器
request = urllib2.Request(url, headers=headers)#因为要使用headers,所以用urllib2
response = urllib2.urlopen(request)
page = response.read() # 生成的是str对象
f = json.loads(page) # json.loads:str转成dict json.load是读取json数据
comments=[]
for i in range(len(f["reviews"])):
comments.append(f["reviews"][i]["comments"])
return comments
if __name__=="__main__":
home = [['12160895', 104], ['15516056', 59], ['15807919', 34], ['15473761', 101], ['7816441', 75], ['8133141', 98],
['6563956', 149], ['11505129', 96], ['13131814', 35], ['15225079', 34], ['15941869', 42], ['10301999', 58],
['8435107', 67], ['9362909', 79], ['16473681', 26], ['18236040', 3], ['15709444', 49], ['6562686', 39],
['16591080', 39], ['18499416', 0]]
dict = {}
for i in range(len(home)):
dict[home[i][0]] = []#只有定义了字典的value值是list之后,才能使用后面的append方法
for a in range(0, home[i][1], 10):
url = 'https://zh.airbnb.com/api/v2/reviews?key=d306zoyjsyarp7ifhu67rjxn52tv0t20¤cy=CNY&locale=zh&listing_id=%s&role=guest&_format=for_p3&_limit=10&_offset=%d&_order=ranked_languages_countries' % (home[i][0], a)
for com in get_comment(url):
dict[home[i][0]].append(com)
print 'get%s No.%d' % (home[i][0], i + 1)#用来显示爬取的进程
f = open('/Users/apple/Desktop/comments_hz_top20.txt', 'w')
f.write(json.dumps(dict, ensure_ascii=False, encoding='UTF-8'))#字典类型输出时要注意使用json.dumps避免乱码
f.close()
一共38行不到的代码,完成了任务,我也获得了TOP20房源的所有评论~
可以看到,TOP20的房子,整体评价都是相当不错的(这不是废话嘛),回归正题,这些优秀的短租房有哪些共同的特点呢?如果找到了这个问题的答案,那么我们也能扬长避短,让我们自己的房子成为Airbnb杭州Top20~
词云分析:
杭州果然是国际化大公园,评论里面中英日韩混杂,还有繁体,这里我们只分析中文:
具体的方法是:利用图悦(在线统计中文词频网页)来统计评论中的中文热词,再运用Tagul(在线制作词云网页,需翻墙)来制作词云,可以参考教程,下面就是我做的结果:
以上:
可以看到,“房东“一词出现的频率是最大的,其次是“西湖““热情““温性““舒服““体验““整洁““交通““姐姐““可爱““地理“等词,看来最好的名宿体验应该是这个样子的:你风尘仆仆地来到杭州,在西湖边碰到了一位邻家姐姐,她可爱、贴心,特别热情,带你去吃了杭州的美食,又带你去逛了安静的茶园;晚上,你住在她家,房间布置得很温馨,设施齐全,干净整洁;住的周围也很便利,交通发达,晚上饿了,你俩又坐地铁去商圈吃宵夜。
不足:
- Airbnb是动态网页,有关房源id和评论数还没能做到自动爬取,下一步准备用爬虫框架来做;
- 评论中还有英日韩三种语言没有利用;
- 抓取得量太少,txt文件只有250k,下一步准备进行分布式;
转载自原文链接, 如需删除请联系管理员。
原文链接:如何才能让你的房子成为Airbnb杭州Top20?,转载请注明来源!