一、requests+lxml非登录爬取豆瓣数据
1、首先打开豆瓣,找到想要爬取的电影短评地址url,例如:
2、打开网页中开发者工具,大部分电脑直接按F12即可,也有不同的,比如ThinkPad使用Fn+F12打开,在页面中找到网络->点击第一行->在右边找到消息头->下滑,找到请求头,记下user-agent
⭐注意:这里的user-agent包含浏览器相关信息和硬件设备信息等,可以伪装成合法的用户请求,否则报错403:服务器上文件或目录拒绝访问
3、代码部分
#引包
import requests as rq
from lxml import etree
#url+headers信息
url = 'https://movie.douban.com/subject/1292001/'
headers = {'User-Agent':'****'}
4、获取网页数据(网页html式样)
⭐非登录状态下使用的是get()方法
data = rq.get(url,headers=headers).text
data的输出结果:
5、获取到网页数据后要对网页进行解析
s = etree.HTML(data)
6、接下来获取网页中元素信息,比如:电影名称,导演,演员,时长等...可手动获取网页信息,如下图:
选中目标标签右键->复制->XPath(盗用网络图片)
7、代码部分
#默认返回的是list列表格式
film = s.xpath('/html/body/div[3]/div[1]/h1/span[1]/text()')
director = s.xpath('/html/body/div[3]/div[1]/div[3]/div[1]/div[1]/div[1]/div[1]/div[2]/span[1]/span[2]/a/text()')
Starring = s.xpath('/html/body/div[3]/div[1]/div[3]/div[1]/div[1]/div[1]/div[1]/div[2]/span[3]/span[2]/a/text()')
duration = s.xpath('/html/body/div[3]/div[1]/div[3]/div[1]/div[1]/div[1]/div[1]/div[2]/span[13]/text()')
print("影名:" , film[0])
print("director:",director[0])
print("Starring:",Starring[0])
print("duration:",duration[0])
二、模拟登录豆瓣爬取短影评
1、模拟登录豆瓣
(1)登录豆瓣的方式有很多种,这里选择密码登录
首先要获取到密码登录的url是什么,这里的url不是浏览器中的网址地址,而是在网络传输中的post请求,先输入错误的账号和密码,以获取url
点击post,这里才是真正的请求网址
接下来准备头信息,在消息头处下滑,找到cookie和user-agent:
然后开始传输用户名和密码,查看传输表单数据:
代码部分:
s = rq.session()
def login_douban():
# 登录URL
login_url = 'https://accounts.douban.com/j/mobile/login/basic'
# 请求头信息
headers = {'User-Agent':'****',
'Cookie':'****'}
# 传递用户名和密码
data = {
'ck': '',
'name':'用户名',
'password':'密码',
'remember':'false',
'ticket': ''}
try:
r = s.post(url=login_url, headers=headers, data=data)
r.raise_for_status()
except:
print("登录请求失败")
return 0
# 打印请求结果
print(r.text)
return 1
2、登录后爬取某一页数据
1、爬取之前先要获取当前页网址,例如获取第一页短评的网址
,点开短评,然后根据下图找到网址,同样的方式,找到user-agent
代码如下:
comment_url = '****'
#请求头
headers ={'user-agent':'Mozilla/5.0'}
try:
r = s.get(comment_url,headers=headers)
r.raise_for_status()
except:
print('爬取请求失败')
return 0
2、爬取请求发送成功后,使用正则表达式提取影评内容
⭐标记:re库主要用于字符串匹配
comments = re.findall('<span class="short">(.*)</span>',r.text)
if not comments:
return 0
3、得到数据后,将其写入文本中(可一行一行写入,也可以全部写入)
with open(COMMENTS_FILE_PATH, 'a+',encoding=r.encoding) as file:
file.writelines('\n'.join(comments))
4、做到这里只可以获取一页上的数据,为了获取更多的数据就要加上翻页功能,在网址
https://movie.douban.com/subj...
中start即开始值,limit是每页显示的数据数量,点开下一页,会发现,start从0开始每次+20,依次向后循环翻页,因此代码中只要修改start值即可实现批量爬取数据,不过豆瓣限制每个账号最多获取500条
`
5、最终获取的数据:
6、将所有数据进行分词后,马上就可以制作词云了~~~
⭐注意:在open中要加入encoding='UTF-8',说明传输文件的编码格式,否则会出现UnicodeDecodeError错误
def cut_word():
with open(COMMENTS_FILE_PATH,encoding='UTF-8') as file:
comment_text = file.read()
wordlist = jieba.cut(comment_text,cut_all=True)
wl = " ".join(wordlist)
print(wl)
return wl
7、最后一步~生成词云
⭐注意:分词和制作词云均需要新的库,有jieba,PIL等,注意引入相应的库
def create_word_cloud():
#设置词云形状图片
wc_mask = np.array(Image.open(WC_MASK_IMG))
#数据清洗词列表
stop_words = ['就是', '不是', '但是', '还是', '只是', '这样', '这个', '一个', '什么', '电影', '没有','呵呵']
#设置词云的配置,如:字体,背景色,词云形状,大小
wc = WordCloud(background_color='red',max_words=255,mask=wc_mask,scale=4,
max_font_size=255,random_state=42,stopwords=stop_words,font_path=WC_FONT_PATH)
#生成词云
wc.generate(cut_word())
plt.imshow(wc,interpolation="bilinear")
plt.axis("off")
plt.figure()
plt.show()
8、词云如下(选用一张大红底色,好丑....)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。