一.前言
为了总结前面所学知识,今天随便爬了一下豆瓣网。使用了requests+xpath,豆瓣网的爬取相对比较简单,可将此网站作为爬虫的入门。
二.爬取需求
爬取每篇文章的用户名,标题,文章简介,图片,点赞量和转发量。
注意:标题和图片有的文章没有
三.说明
1.登录豆瓣
2.文章的刷新,重复请求这个url即可实现文章的刷新,以下代码只刷新了3次
四.代码演示
# encoding=gbk
import requests
import json, os
from lxml import etree
url = "https://accounts.douban.com/j/mobile/login/basic"
header = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"
}
# name和password是登录豆瓣网的账号的密码
fromdata = {
"name": "XXXXXXX",
"password": "XXXXXXX"
}
# 将表单数据序列化
data = json.dumps(fromdata)
# 发送post请求 使用session建立持久会话
session = requests.session()
response1 = session.post(url=url, data=fromdata, headers=header)
# 新建一个文件夹用于存放豆瓣图片
if not os.path.exists("./豆瓣数据"):
os.mkdir("./豆瓣数据")
# 判断是否请求成功
if response1.status_code == 200:
count = 1
# 爬取 3 页数据
while count <= 3:
# 每次请求这个url都会刷新页面内容
response = session.get("https://www.douban.com/explore/", headers=header)
# 使用etree继续html
html = etree.HTML(response.text)
dicts = {}
album = []
items = html.xpath('//*[@id="gallery_main_frame"]/div[@class="item"]')
if not os.path.exists(f"./豆瓣数据/第{count}页数据"):
os.mkdir(f"./豆瓣数据/第{count}页数据")
for item in items:
# 获取用户名,文章简介,标题,并将其转换成字符串
username = "".join(item.xpath('./div[@class="hd"]/div[@class="usr-pic"]/a[2]/text()'))\
.encode("gbk","ignore").decode("gbk")
# \表示本行代码换行
detail = "".join(item.xpath('./div[@class="bd"]/div/p[1]/text()')).strip()\
.encode("gbk", "ignore").decode("gbk")
titles = "".join(item.xpath('./div[@class="bd"]//div[@class="title"]/a/text()'))
likes_forword = item.xpath('div[@class="actions"]//span/text()')
likes = likes_forword[0] + "赞"
forwords = likes_forword[1] + "转发"
# 将以上信息存入字典
dicts["username"] = username
dicts["titles"] = titles
dicts["detail"] = detail
dicts["likes"] = likes
dicts["forwords"] = forwords
# 获取所有图片链接,其中可能会有空列表
photos_album = "".join(item.xpath('./div[@class="bd"]//div[@class="photos"]/a/@href'))
dicts['photos'] = photos_album
file = open(f"./豆瓣数据/第{count}页数据/第{count}页文本数据", "at").write(str(dicts) + "\n")
# 筛选存在图片链接的列表
if len(photos_album) == 0:
pass
else:
# 存入列表
album.append(photos_album)
# 下载图片
if not os.path.exists(f"./豆瓣数据/第{count}页数据/第{count}页图片"):
os.mkdir(f"./豆瓣数据/第{count}页数据/第{count}页图片")
for n in range(len(album) - 1):
response = session.get(album[n], headers=header)
file = open(f"./豆瓣数据/第{count}页数据/第{count}页图片/{n + 1}.jpg", "wb").write(response.content)
# 计数器自增,爬取下一页
count +=1
五.运行结果
已经生成了每页数据文件夹,每页图片另外放在一个文件夹中