1.准备:
1) Python开发环境, 笔者用的是3.7.4; 工具用的是Pycharm
2) scrapy安装
关于安装scrapy的安装教程网上有很多的教程,这里不再赘述.
2.上路:
a).登陆
首先要请求登陆页面, 如下图
这里我们重写start_request()
把header中的use agent放到了setting.py的文件下:
请求下来的Response由login()处理:然后使用FormRequest函数post登陆豆瓣, 我们先输入一个错误的账号和密码查看豆瓣需要post的参数信息:
ck: "", 防空即可;
name:"", 就是登陆用户名
password:"", 密码
remember: 是否记住账号, 可以改成true
ticket:"", 放空即可;
代码如下:
b).获取评论
登陆成功之后,我们开始请求评论信息:也就是下面的这个链接:
https://movie.douban.com/subject/26794435/collections
请求前10页评论的代码如下
分析页面的元素信息获取评论:
我们想要获取的是真正有用的评论信息,但是这个评论信息是包含在p标签里面的,没有明显的id和value可以用,如果只是提取p标签的信息那么会包含太多的内容。所以我么退回去使用td valigin ='top'这个元素进行定位,具体代码信息如下:
需要注意的是这里面的global COMMENTS中的COMMENTS是我在上面定义的一个全局变量,我这里没有使用item。
提取的评论中包含了只有日期没有具体评论文字的信息,所以我使用了一个正则表达式过滤了日期信息。
c).生成词云
我们要在爬虫完成,要关闭的时候进行词云输出,所以我们重写了Close()函数,具体代码如下:
生成代码的时候需要用到wordcloud和jieba模块,相关安装信息这里不赘述.
3.结果展示:
4.源代码展示:
# -*- coding: utf-8 -*-
import scrapy
import json
import re
import wordcloud
import jieba
COMMENTS =""
class NezhacommentSpider(scrapy.Spider):
name ='NezhaComment'
# allowed_domains = ['movie.douban.com']
# start_urls = ['https://movie.douban.com/subject/26794435/collections']
def start_requests(self):
start_url ="https://accounts.douban.com/passport/login"
header = {
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
'Accept-Encoding':'gzip, deflate',
'Accept-Language':'zh-CN,zh;q=0.9',
'Cache-Control':'max-age=0',
'Connection':'keep-alive',
'Host':'accounts.douban.com',
'Referer':'https://movie.douban.com/subject/26794435/?from=showing',
'Upgrade-Insecure-Requests':'1'
}
yield scrapy.Request(start_url,callback=self.login,headers=header, dont_filter=True)
def login(self, reponse):
login_url ="https://accounts.douban.com/j/mobile/login/basic"
login_header = {
'Accept':'application/json',
'Content-Type':'application/x-www-form-urlencoded',
'Origin':'https://accounts.douban.com',
'Referer':'https://accounts.douban.com/passport/login',
'X-Requested-With':'XMLHttpRequest'
}
form_data = {
'ck':'',
'name':'15060197943',
'password':'xiaolong35..',
'remember':'true',
'ticket':''
}
print("start login...")
yield scrapy.FormRequest(login_url,headers=login_header,formdata=form_data,callback=self.afterlogin)
def afterlogin(self,response):
print(response.url)
print('after login...')
comment_url ="https://movie.douban.com/subject/26794435/collections"
# 抓取10页
for iin range(0, 10):
if i ==0:
yield scrapy.Request(comment_url, callback=self.parse)
else:
next_page ="?start=page".replace("page",str(i*20))
yield scrapy.Request(comment_url + next_page, callback=self.parse)
def parse(self, response):
# 获取所有本页所有评论
td =response.xpath("//td[@valign='top']/p/text()").extract()
print("total %d comments in current page" %len(td))
global COMMENTS
for commentsin td:
#排除日期格式
comments = comments.strip()
match = re.search(r'\d{4}-\d{1,2}-\d{1,2}',comments)
if match:
continue
COMMENTS = COMMENTS + comments
def close(spider, reason):
#爬虫结束时生成词云
wc = wordcloud.WordCloud(font_path='C:/WINDOWS/Fonts/STHUPO.TTF', max_words =3000, width=1000, height=500)
print(COMMENTS)
sg_list = jieba.cut(COMMENTS, cut_all=False)
text ='/'.join(sg_list)
wc.generate(text)
wc.to_file('nezha.jpg')
print('finish scraping, spider closing...')