【自用】Python爬虫学习(三):图片下载、使用代理、防盗链视频下载、多线程与多进程

使用BeautifulSoup解析网页并下载图片

目的:对某网站的某个专栏页面的图片进行下载得到高清图。
思路:从主页获取每张图片对应的子页面的链接地址,在子页面找到对应的高清图片下载地址然后下载。查找使用BeautifulSoup,直接从主页拿到的图片下载链接为缩略图,这里想要下载的是高清的图片。

import time
import requests
from bs4 import BeautifulSoup

domain = "https://www.umei.cc/"
# url = "https://www.umei.cc/bizhitupian/weimeibizhi/"  # 唯美壁纸专栏
url = "https://www.umei.cc/bizhitupian/fengjingbizhi/"  # 风景壁纸专栏
# 浏览器的标头身份标识信息
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36 Edg/127.0.0.0"
}

resp = requests.get(url, headers=headers)
print("服务器响应状态码:", resp.status_code)
resp.encoding = 'utf-8'  # 处理乱码

# 把主页源代码交给BeautifulSoup
main_page = BeautifulSoup(resp.text, "html.parser")
# 获取图片子页源码链接
alist = (main_page.find("div", class_="item_list infinite_scroll").
         find_all("a", class_="img_album_btn"))

# print(alist)
img_num = 0
for a in alist:
    href = a.get('href')  # 直接通过get就可以拿到属性的值
    child_url = domain + href.strip('/')
    # print(child_url)  # 子页面网址

    # 拿到子页面的源代码
    child_page_resp = requests.get(child_url, headers=headers)
    child_page_resp.encoding = 'utf-8'

    # 从子页面中获取图片的下载路径
    child_page = BeautifulSoup(child_page_resp.text, "html.parser")
    div_list = child_page.find('div', class_='big-pic')
    image_src = div_list.find('img').get('src')  # 用get拿到标签的对应属性
    image_name_src = div_list.find('img').get('alt')[:-1] + '.jpg'

    # print(image_src)  # 打印图片下载地址,http://kr.shanghai-jiuxin.com/file/bizhi/20220927/5wn4old1jef.jpg
    # print(image_name_src)  # 红色,爱心,心,玫瑰,叉子,刀.jpg

    # 下载图片
    img_resp = requests.get(image_src)

    # 获取url中最后一个/以后的内容作为图片名称
    # img_name_url = image_src.split('/')[-1] #5wn4old1jef.jpg
    with open("data_file/img/" + image_name_src, mode='wb') as f:
        f.write(img_resp.content)  # img_resp.content #这里得到的是字节数据
    img_num = img_num + 1
    print(f"Download successfully!\t{img_num}:'{image_name_src}'")

    # 只下载前6景图片
    if img_num == 6:
        img_resp.close()
        child_page_resp.close()
        break
    time.sleep(3)  # 每下载一张图片休息3s
print("Over!!!")
resp.close()

模拟用户登录处理

  • 方法1:使用会话session对象,使用session.get()、session.post()进行请求
session = requests.session()
resp = session.post()
# resp = session.get()
  • 方法2:使用requests.get(),在headers中设置参数,直接从浏览器中复制对应的Cookie
resp = requests.get(url=url, headers={"Cookie": "一长串内容"})
# !!!注:代码不能正常运行,仅做示例!!!
# 登录->得到cookie,带着cookie 去请求服务器
# 使用session进行请求->session你可以认为是一连串的请求。在这个过程中的cookie不会丢失
import requests

# 登录账户与密码信息(仅做示例)
data = {
    "loginName": "15100001234",
    "password": "1234abcd"
}

# 会话
session = requests.session()

# 1.登录
url = "https://passport.17k.com/ck/user/login"
resp = session.post(url, data=data)
# print(resp.json())
print(resp.cookies)

# 2.拿书架上的数据
# 刚才的那个session中是有cookie的
url2 = 'https://user.17k.com/ck/author/shelf?page=1&appkey=2406394919'
resp1 = session.get(url=url2)  # 第一种方法
print(resp1.json())

resp2 = requests.get(url=url2, headers={
    # 第二种方法,使用requests.get(),在headers中设置参数,直接从浏览器中复制对应的Cookie
    "Cookie": "GUID=abcdfa-adg-ag;c_channel=0;c_csc=web;UM_distinctid=177=1614336271"
    # 实际的Cookie很长一串,这里仅做示范瞎写的
})
print(resp2.text)

使用代理

请求时传入一个proxies参数

resp = requests.get(url, proxies=proxies)
# 代码不能正常运行,仅做示例,想要正常运行需要寻找可用的代理IP节点
import requests

# 218.60.8.83:3129 找一个可用的代理IP
proxies = {
    "https": "https://218.60.8.83:3129"
    # "http": ""#具体使用哪种看具体的网站
}

url = "https://www.baidu.com"

resp = requests.get(url, proxies=proxies)
print("服务器响应状态码:", resp.status_code)
resp.encoding = 'utf-8'  # 处理乱码
print(resp.text)

视频下载,防盗链的处理

根据某视频文章页面的网页链接下载文章对应的视频
思路:

  1. 拿到contId
  2. 拿到videoStatus返回的json.-> srcURL
  3. 对srcURL内容进行修正
  4. 下载视频

防盗链,添加一个参数

"referer": url
import requests

url = "https://www.pearvideo.com/video_1795368"
# url = "https://www.pearvideo.com/video_1689388"

contId = url.split("_")[1]  # 1795368
# print(contId)

videoStatusUrl = f"https://www.pearvideo.com/videoStatus.jsp?contId={contId}&mrd=0.7991879511806432"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36 Edg/127.0.0.0",
    # 防盗链,溯源,当前本次请求的上一级是谁
    "referer": url
}

resp = requests.get(videoStatusUrl, headers=headers)
# print(resp.text)

dict = resp.json()
srcUrl = dict['videoInfo']['videos']['srcUrl']  # 返回的虚假的地址
# print(srcUrl)
systemTime = dict['systemTime']

relSrcUrl = srcUrl.replace(systemTime, f"cont-{contId}")  # 寻找规律进行替换得到的真实的地址
print(relSrcUrl)

# srcUrl: "https://video.pearvideo.com/mp4/short/20240802/1723116619381-16034050-hd.mp4" 返回的虚假的地址
# relUrl: "https://video.pearvideo.com/mp4/short/20240802/cont-1795368-16034050-hd.mp4"  实际真实的地址
#          https://video.pearvideo.com/mp4/short/20240802/cont-1795368-16034050-hd.mp4

# 根据真实下载地址下载视频
with open(f"{contId}.mp4", mode='wb') as f:
    f.write(requests.get(relSrcUrl).content)

print("Over!!!")
resp.close()

多线程与多进程

# 线程,进程
# 进程是资源单位,每一个进程至少要有一个线程
# 线程是执行单位

# 启动每一个程序默认都会有一个主线程
def func():
    for i in range(100):
        print("func", i)


if __name__ == '__main__':
    # print("hello wolrd")
    func()
    for i in range(100):
        print("main", i)

多线程的第一种写法

# 多线程
from threading import Thread  # 线程类

# 多线程的第一种写法
def func():
    for i in range(100):
        print("func", i)


if __name__ == '__main__':
    t = Thread(target=func)  # 创建线程并给线程安排任务
    t.start()  # 多线程状态为可以开始工作状态,具体的执行时间由CPU决定

    for i in range(100):
        print("main", i)

多线程的第二种写法

# 多线程
from threading import Thread  # 线程类

# 多线程的第二种写法
class MyThread(Thread):
    def run(self):
        for i in range(100):  # 固定的 -->当线程被执行的时候,被执行的就是run()
            print("子线程", i)


if __name__ == '__main__':
    t = MyThread()  # 创建线程并给线程安排任务
    # t.run()  # 注意,这种写法会被当成方法的调用.-->成为单线程
    t.start()  # 开启线程

    for i in range(100):
        print("主线程", i)

多线程的传参

from threading import Thread  # 线程类

# 多线程的传参
def func(name):
    for i in range(100):
        print(name, i)


if __name__ == '__main__':      
    # 传递参数必须是元组,逗号不能省,不能写成args=("周杰伦")
    t1 = Thread(target=func, args=("周杰伦",))
    t1.start()

    t2 = Thread(target=func, args=("王力宏",))
    t2.start()

多进程

from multiprocessing import Process # 进程类

def funcc():
    for i in range(100):
        print("子进程", i)


if __name__ == '__main__':
    p = Process(target=funcc)
    p.start()

    for i in range(100):
        print("主进程", i)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lucky_云佳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值