我的环球旅行梦
制作一个和旅行相关的Python项目,希望在未来可以一边完善自己的作品一边四处游玩。(第一次写博客,小白)
1. 项目功能简介
(1)能获取到携程用户的关于自己旅游过的景点评论数据;
(2)对每一个用户的评论数据都做了分析,然后创建对应的mysql数据库表;
(3)使用Python里面的jieba库对评论数据进行分析;
(4)分析得到的热词,制作成词云的方式展示出来。
-
隐藏的亮点
a,得到的用户评论以二进制的形式保存在数据库里面,可以很方便的取出评论展示给大家查看。 b,用户上传的评论图片可以在数据库里取出来,也可以根据数据库的链接在网上显示出来,我们也可以知道具体是哪一个用户上传的旅游照片。 c,在保存例如:鼓浪屿这个地方的各个旅游景点的poiID和resourceId保存在MongoDB里面(MongoDB是非关系型数据库,第一次尝试感觉还不错)。
2. 开发具体步骤
前言:
我的目标是制作一个神器,可以帮助像我一样爱旅行爱生活的小宝贝。神器可以帮助路痴,小白的宝贝提供准确,全面的旅游信息和建议,以及为你的旅行提供及时方便的功能。
(1)首先去携程里的鼓浪屿速览看一下要爬取的页面,大概发现有几十个景点,每个景点的结构应该都是差不多的,因此我们选择第一个景点进去看看具体的页面应该如何爬取。
这是第一个景点页面
通过查看传回的数据我们可以得到这就是我们所要的接口,使用的是post进行传输,传输的Form Data 有很多字段,可以大概分析出来
经过上面的查看我们能够分析出来在鼓浪屿这个地方,能够通过改变poiID,pagenow和resourceId三个值来动态获取关于鼓浪屿的用户评论,pagenow表示的当前页(最多有100页),与景点相关的是poiID,resourceId。(携程会进行反爬虫,我采用随机休眠的方式来爬取数据,这里的休眠的时间不能太低)
因此我们首先去获取鼓浪屿所有景点的poiID,resourceId(这个比较简单,省略哦):
核心代码
for i in range(1, 2):
try:
req = requests.get(base_url.format(i), headers=headers)
soup = BeautifulSoup(req.content.decode('utf-8'), 'html.parser')
rdetailbox = soup.find_all('div', {'class': 'rdetailbox'})
print('---------------',len(rdetailbox))
for u in rdetailbox:
url = second_url + u.dl.dt.a['href']
get_poiid = requests.get(url, headers=headers)
poiid_soup = BeautifulSoup(get_poiid.content.decode('utf-8'), 'html.parser')
comment_entrance = poiid_soup.find('div', {'class': 'comment_entrance'})
poiid = comment_entrance.span.a['data-id']
data = {
'Name': u.dl.dt.a['title'],
'resourceId': url.split('/')[-1][:-5],
'poiID': poiid
}
print(data)
# 将得到的景点数据插入MongoDB
profile.insert(data)
final_data.append(data)
except Exception as e:
print(e)
pass
df = pd.DataFrame(final_data, columns=['Name', 'poiID', 'resourceId'])
df.to_csv('./data/ctrip_Xiecheng.csv', encoding='utf-8')
MongoDB的配置(运行获取动态参数的Python文件时,需要启动MongoDB)
# 配置pymongo
mongo_client = MongoClient('localhost', 27017)
spider = mongo_client['ctrip']
profile = spider['ma']
还有一部分是获取评论的代码,私聊给你哦
(2)如何根据获取到用户信息建表(这个因人而异,我只是参考别人的创意加上自己的思考创建的表)
建表的时候,一定要考虑全面!!!我当时就没有考虑到图片存储的大小,有必要的时候在命令行修改数据库的参数。我当时因为这个错误浪费了几个周,嘻嘻~都怪自己太笨了。具体操作如下:
mysql> show global variables like 'max_allowed_packet';
#修改参数:
mysql> set global max_allowed_packet=1024*1024*16;
mysql> show global variables like 'max_allowed_packet';
(4)我的修行有限,没有对评论数据做太多分析,只是粗略的取出来出现次数最多的‘词语’,sorry!
全部代码如下:
import os, codecs
import jieba
from collections import Counter
def get_words(txt,fobj):
seg_list = jieba.cut(txt)
c = Counter()
for x in seg_list:
if len(x) > 1 and x != '\r\n':
c[x] += 1
print('常用词频度统计结果')
for (k, v) in c.most_common(100):
print('%s%s %s %d' % (' ' * (5 - len(k)), k, '*' * int(v / 3), v))
inStr=k+':'+str(v)
fobj.write(inStr)
fobj.write("\n")
def createFile():
# 热词的存储
fname="word/"+input("输入文件名:")
while True:
if os.path.exists(fname):
print("ERROR:'%s' already exists" % fname)
fname = "word/"+input("输入文件名:")
else:
break
return fname
if __name__ == '__main__':
fname=createFile()
fobj = open(fname, 'w', encoding="utf-8")
with codecs.open('word/px.txt', 'r', 'utf8') as f:
txt = f.read()
get_words(txt,fobj)
后期会采用框架,还有一些算法完善jieba分词功能。马上就期末,我要复习(灬ꈍ ꈍ灬)。
(4)利用Python把图片作为词云背景,词云的来源就是第三步得到的。
原始图:
词云图:
核心代码如下:
def GetWordCloud():
path_txt = 'word/xp.txt'
path_img = "picture/px.jpg"
f = open(path_txt, 'r', encoding='UTF-8').read()
background_image = np.array(Image.open(path_img))
# 结巴分词,生成字符串,如果不通过分词,无法直接生成正确的中文词云,感兴趣的朋友可以去查一下,有多种分词模式
# Python join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串。
cut_text = " ".join(jieba.cut(f))
wordcloud = WordCloud(
# 设置字体,不然会出现口字乱码,文字的路径是电脑的字体一般路径,可以换成别的
font_path="C:/Windows/Fonts/simfang.ttf",
background_color="white",
# mask参数=图片背景,必须要写上,另外有mask参数再设定宽高是无效的
mask=background_image).generate(cut_text)
# 生成颜色值
image_colors = ImageColorGenerator(background_image)
# 下面代码表示显示图片
plt.imshow(wordcloud.recolor(color_func=image_colors), interpolation="bilinear")
plt.axis("off")
plt.show()
代码就不完全展示出来咯,等我把分词那部分功能写好再说。虽然有点可恶,我相信你能理解我,(●´З`●)
3. 个人心得与打算
关于学习的:
以前不能理解我为什么要学习那么多的知识,就像柯景腾说的:十年后,我连log是什么都不知道,也能活得好好的。对于基本的知识是我们每个人都应该具有的,但是对于深入的知识就需要由自己的兴趣去选择学习。就好比每一个正常人都要能够使用小学算术去买菜,但是如果想要当数学家,那他就必须要知道log是啥。
关于这个项目的:
我会在后期做一个web项目,将Python处理收集到的数据,显示在系统里面,也会提供相应的功能。这个项目将会放在我买的服务器上面,供大家来使用。