经常在网上看到图包合集,动不动就几百张,吓skr人,各种小姐姐,美得不像话。在看完之后,我情绪逐渐稳定,开始思考人生的意义,啊不,是技术的真谛! 学习Python中有不明白推荐加入交流群
号:516107834
群里有志同道合的小伙伴,互帮互助,
群里有不错的学习教程!
我在想那么多图片,如果都从网上一张张的右键,然后另存为图片,还没弄完,估计鼠标就已经狗带了。那么有什么办法能把这些图片一次性全down下来呢?毫无疑问,爬虫是不二之选。
说时迟,那时快,我就准备开始先拿百度贴吧下手了,为什么是贴吧呢?因为我听说校花吧还有美女吧里的小姐姐还不错,具体听谁说的,额,我也忘了,反正不要在意这些细节啦。
思路大致如下,先访问校花吧的首页,找到帖子总数。然后根据贴吧默认每页50条帖子,计算出总页数。通过观察第3页的链接
http://tieba.baidu.com/f?kw=校花吧&ie=utf-8&pn=100
可以发现pn这个参数应该就是表示从第几条帖子开始的,每页50条, 第3页开始的帖子正好是50*(3-1)=100。发现这个规律后就好办了,使用for循环拼接出每一页的url
然后根据当前url获取这一页的所有帖子,解析出帖子详细内容的链接
最后请求帖子详细内容页面,解析出每张图片的url,逐个保存即可。
当我写完代码,期待的搓搓手,点击运行,发现没有任何动静,然后一步步调试,发现获取到的图片url列表为空。这是为啥呢?我跑去看贴吧网页的源代码,发现里面有些东西被注释了,似乎跟用户是否登录有关。会不会是这样,在你登录之前和登录之后,接口给你展示的东西是不一样的,包括这些图片。但是在浏览器上作为普通用户查看,登不登录并没有什么区别,我想这可能是贴吧的一种反爬措施吧。于是我就使用requests的Session先模拟登录,再请求帖子数据,大功告成。完整代码如下:
"""
Function:爬取贴吧帖子图片并保存到本地
Author:KevinWong
Time:2018年10月17日22:17:08
"""
import requests, math,os.path
from bs4 import BeautifulSoup
def main():
session = login()
keyword = input('请输入贴吧名称:')
# 构建贴吧主页url
index_url = "https://tieba.baidu.com/f?kw={0}".format(keyword)
# 获取帖子总页数(经过测试发现不登录的情况下是无法获取帖子数目的)
total_page = get_total_page(index_url, session)
# 获取每一页的帖子url 放在列表中
all_tiezi_urls = get_tiezi_url_list(total_page, keyword, session)
"""
以“关键字/数字序号.jpg”的形式保存爬取的图片
判断文件夹是否存在 如果不存在 则先创建文件夹
"""
img_dir = "C:/Users/Administrator/Desktop/" + keyword
if (not os.path.exists(img_dir)):
os.mkdir(img_dir)
i = 0
for each in all_tiezi_urls:
# 获取帖子的具体内容
res = session.get(each)
# 从中解析出图片url
soup = BeautifulSoup(res.text, 'html.parser')
img_urls = soup.find_all('img', class_='BDE_Image')
for img in img_urls:
i = i + 1
with open(img_dir + "/" + str(i) + '.jpg', 'wb') as f:
print("正在下载第" + str(i) + "张图片" )
f.write(session.get(img.attrs['src']).content)
print("图片下载完毕!")
# 模拟登陆的方法
def login():
# 登录的用户名
username = '15686220830'
# 登录的密码
password = 'KevinWong*****'
# 登录所需的参数
login_data = {
'username': username,
'password': password,
'u': 'https://passport.baidu.com',
'tpl': 'pp',
'staticpage': 'https://passport.baidu.com/static/passpc-account/html/v3Jump.html',
'isPhone': 'false',
'charset': 'utf-8',
'callback': 'parent.bd_pcbs_ra48vi'
}
# 构造所需的headers
headers = {
"user-agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36"
}
# 登录的url
baidu_loginurl = "https://passport.baidu.com/v2/api/?login"
# 创建session
session = requests.session()
# 模拟登陆
session.post(baidu_loginurl, login_data, headers=headers)
# 创建session
return session
# 获取总页数的方法
def get_total_page(url, session):
# 获取网页内容
res = session.get(url)
# 解析出帖子总数
soup = BeautifulSoup(res.text, 'html.parser')
tiezi_total_num = soup.find('span', class_='card_infoNum').text
tiezi_total_num = int(tiezi_total_num.replace(',', ''))
# 贴吧默认每页50条帖子
page_size = 50
# 计算出总页数
total_page = math.ceil(tiezi_total_num / page_size)
return total_page
# 获取帖子url列表的方法
def get_tiezi_url_list(total_page, keyword, session):
"""
此处演示爬取美女吧图片 由于帖子数太多 总页数有72w+
为了节省爬取时间 此处只爬取前1页
"""
all_tiezi_urls = []
for i in range(1, 2):
# 构造url
tiezi_url = "http://tieba.baidu.com/f?kw=" + keyword + "&pn=" + str((i - 1) * 50)
# 获取每一页的帖子url
tiezis = get_tiezi_list(tiezi_url, session)
# 将所有帖子url加入到all_tiezi_urls中
all_tiezi_urls.extend(tiezis)
return all_tiezi_urls
# 获取当前页所有帖子列表的方法
def get_tiezi_list(tiezi_url, session):
# 获取某个帖子列表页面的网页内容
res = session.get(tiezi_url)
# 从中解析出每个帖子的链接
soup = BeautifulSoup(res.text, 'html.parser')
a_list= soup.find_all('a', class_='j_th_tit ')
# 拼接出真实的帖子链接
static_tiezi_urls = []
for each in a_list:
static_tiezi_urls.append("http://tieba.baidu.com" + each.attrs['href'])
return static_tiezi_urls
if __name__ == '__main__':
main()
运行结果如下:
为了节省爬取时间,仅仅爬取了第一页帖子里的所有图片,总共128张,有耐心的小伙伴可以把这个爬虫部署到阿里云上,让它没日没夜的爬,爬到你看的想吐,爬到贴吧瘫痪,爬到世界尽头。完结,撒花,ye~
下篇文章不写爬虫,来个番外篇,实战如何将你的女神照片变成字符画,效果如下(很魔性很有艺术感啊有木有!):
如果需要源码、视频教程和小姐姐玉照,请关注 私信小编007即可获取到渠道。
网友评论