豆瓣电影top250下的评论爬取
程序员文章站
2022-05-02 17:43:19
...
近日想要试试文本分类的小demo,需要有足够大量的好评差评数据,在研究了一些点评网站后,我选择了豆瓣电影top250豆瓣电影TOP250,这个网上的评价质量高,而且网页结构清晰明显,好爬取。美中不足的是每个电影的评价(好评以及差评)只能爬取各前200条,并且爬了太多(估计是访问100页左右)之后就封IP,一天后解封。后来换了手机提供的WLAN热点之后就再也没有封得掉我,不知道其中是什么原理?
思路:
1.需要爬取的页面连接特别好找,需要注意的是有的评论是繁体字,需要转换成简体字,我在这个博客找到了方法 Python 繁体中文与简体中文相互转换
2.因为之后我直接对句子分词,因此在数据爬取的时候直接把标点符号去掉了,只留下汉字
3.得到的评论数据提供下载豆瓣评论数据,有一些评论使用了颜文字,不过实在是有一些特殊符号去不掉了。数据共60856条,好评1(4-5星)差评0(1-2星)各一半左右。
预览:
爬虫代码:(langconv请Python 繁体中文与简体中文相互转换中下载)
import urllib.request
import urllib.error
import re
import time
import langconv
def Traditional2Simplified(sentence): # 将sentence中的繁体字转为简体字
sentence = langconv.Converter('zh-hans').convert(sentence)
return sentence
# 清理一下评论数据
def clear(string):
if '<p class="">' in string:
string = string.replace(r'<p class="">', "")
if "\n" in string:
string = string.replace("\n", "")
if " " in string:
string = string.replace(" ", "")
string = string.strip() # 去掉空格等空白符号
string = re.sub("[A-Za-z0-9]", "", string) # 去掉英文字母 数字
string = re.sub(r"[!!?。。,&;"★#$%&'()*《》+-/:;<=>@[\]^_`{|}~⦅⦆「」、、〃「」『』【】"
r"〔〕〖〗〘〙#〚〛〜〝〞/?=~〟,〰–—‘’‛“”„‟…‧﹏.]", "", string) # 去掉中文符号
string = re.sub(r"[!\'\"#。$%&()*+,-.←→/:~;<=>[email protected][\\]^_`_{|}~", "", string) # 去掉英文符号
return Traditional2Simplified(string).lower() # 所有的英文都换成小写
# 给一个电影的编号,输出这个电影的评论,好评差评各自200条
def print_movie(movie_num):
for page in range(0, 10):
for judge in ['h', 'l']: # hl对应着好评/差评,中评忽略
try:
url = "https://movie.douban.com/subject/" + str(movie_num) + "/comments?start=" + str(page*20) + \
"&limit=20&sort=new_score&status=P&percent_type=" + judge # 导入总的网址,包括第几页
html = urllib.request.urlopen(url).read().decode("utf-8", "ignore") # 解码这个网页
total_str = re.findall(r'allstar([\s\S]*?)</p>\n', html) # 所有的用户评论数据,应该有20条
for i in range(len(total_str)):
comments = re.findall('<p class="">([\s\S]*?)\n', total_str[i])
cleaned_comment = clear(comments[0]) # 清理一下这个评价
if len(cleaned_comment) > 10: # 太短的评价并不需要
if total_str[i][0] == '1' or total_str[i][0] == '2': # 第一个字就是评价的star数
print("0 " + cleaned_comment)
if total_str[i][0] == '4' or total_str[i][0] == '5': # 并不包括中评
print("1 " + cleaned_comment)
time.sleep(1)
except urllib.error.HTTPError or NameError or ConnectionAbortedError or IndexError as e:
continue
# 首先进入top250界面,查找i页的25个电影编号:
for page in range(1,11):
url_250 = "https://movie.douban.com/top250?start=" + str(25*page) + "&filter="
html_250 = urllib.request.urlopen(url_250).read().decode("utf-8", "ignore") # 解码这个网页
global total_num_str
total_num_str = re.findall(r'https://movie.douban.com/subject/[\d]+/">', html_250) # 所有的用户评论数据,应该有20条
for i in range(len(total_num_str)):
total_num_str[i] = re.sub("\D", "", total_num_str[i])
for movie in total_num_str:
print_movie(movie)