Python入门到实战(七)爬虫获取豆瓣电影TOP250、多线程、Request、BeautifulSoup、HTML/CSS/JavaJcript、开发者工具、HTTPS请求、域名IP

I 前置知识准备:

目标网站的网站结构

爬虫的学习需要对前端技术和网络请求原理有些许了解,在这里,简要提一下。

网络客户端技术:

HTML

超文本标记语言(英语:HyperText Markup Language,简称:HTML)是一种用于创建网页的标准标记语言、标记语言简单理解,就是一致的语义空间下,怎么做的问题。比如

标签中放文字,<div>标签就像一个容器,<title>是网页的标题…

那么在拿到HTML代码直接按照标签读就可以,用栈结构应该就能实现。入一个标签代表什么,直到入一个尾标签,不断出栈,将中间的内容都理解为xxx就可以。

CSS

层叠样式表(英文全称:Cascading Style Sheets)是一种用来表现HTML(标准通用标记语言的一个应用)或XML(标准通用标记语言的一个子集)等文件样式的计算机语言。CSS不仅可以静态地修饰网页,还可以配合各种脚本语言动态地对网页各元素进行格式化。
CSS通俗来说就是负责装饰,装潢作用。

JavaScript

JavaScript(简称“JS”) 是一种具有函数优先的轻量级,解释型或即时编译型的编程语言。虽然它是作为开发Web页面的脚本语言而出名,但是它也被用到了很多非浏览器环境中,JavaScript 基于原型编程、多范式的动态脚本语言,并且支持面向对象、命令式和声明式(如函数式编程)风格。
JS通俗来说负责页面动态处理,比如用户点击,如何响应,路由、传参等、

开发者工具查看前端代码

以上三种语言都可以出现在同一个网页前端代码里,想看代码十分容易,摁F12,或者选择浏览器的开发者工具就可以查看网页源代码。
在这里插入图片描述

网络请求原理

HTTP(hyperText transfer protocol)

超文本传输协议是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。

C/S

上面的三种语言为什么叫网络客户端技术,因为这是直接展示给用户观看的,以人性化的界面,方便用户操作,降低软件,平台的使用难度
用户无需管服务端,后台数据库等如何进行操作的。只许在屏幕点击几下就能完成业务流程
所谓CS架构,就是client 对server架构、也称作 browser /server架构

当今网络大环境仍然还是多用户对服务器,数据在传输过程中也会经过诸多结点,由于http都是明文传输,为了避免数据被篡改和窃听,在密码学的基础上衍生出了HTTPS

HTTPS

HTTPS其实就要用到SSL:Secure Sockets Layer 安全套接字协议
在应用层和传输层进行加密,此处涉及密码学和网络安全知识,不详细展开

域名/IP

IP是Internet Protocol(网际互连协议)的缩写,是TCP/IP体系中的网络层协议。设计IP的目的是提高网络的可扩展性:一是解决互联网问题,实现大规模、异构网络的互联互通;二是分割顶层网络应用和底层网络技术之间的耦合关系,以利于两者的独立发展。根据端到端的设计原则,IP只为主机提供一种无连接、不可靠的、尽力而为的数据包传输服务。
IP就是接到互联网上的主机,需要与别的主机沟通交流,需要有一个唯一标识符~,就是IP,抽象出来,网络层中是通过IP来找端的。
由于IP地址具有不方便记忆并且不能显示地址组织的名称和性质等缺点,人们设计出了域名,并通过网域名称系统(DNS,Domain Name System)来将域名和IP地址相互映射,使人更方便地访问互联网,而不用去记住能够被机器直接读取的IP地址数串。
此处不展开论述

工具:

Request可以轻松实现HTTP请求
BeautifulSoup可以轻松解析网页结构

II 编写代码

安装库

pip install beautifulsoup4
pip install lxml
pip install requests
pip install fake-useragent

如果长时间安装不下来或者安装失败请参考我几天前写的:
Python入门到实战(五)自动化办公…pip install xx 切换国内镜像服务器下载,解决下载慢的问题

分析网页

仔细观察,
URLhttps://movie.douban.com/top250?start=0&filter=
在这里插入图片描述

每点击一下,?start=25,观察得知是25的倍数,其他不变,故只需通过定一个变量i从0-多少页去乘25即可,这个页面是start=50:
在这里插入图片描述
由上可以写一个测试:

import os
print("工作目录",os.getcwd())
download_path='./douban'
if not os.path.exists(download_path):
    os.makedirs(download_path)

def main():
    start_url=['https://movie.douban.com/explore']
    for i in range(1,10):
        start_url.append(f'https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start={i*20}')
    print(start_url)
if __name__=='__main__':
    main()

结果

['https://movie.douban.com/explore', 'https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=20', 'https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=40', 'https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=60', 'https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=80', 'https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=100', 'https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=120', 'https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=140', 'https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=160', 'https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=180']
PS C:\Users\ASUS\Desktop\MLCode\utilPython> 

随便点一个start80,摁住CRTL+鼠标左键,就会用浏览器跳转到相应页面

开始代码

安装完成后,可以打开编辑器撸代码了

import os
import requests
from bs4 import BeautifulSoup
from urllib.request import urlretrieve

download_path='./dbTop250'
if not os.path.exists(download_path):
    os.makedirs(download_path)

def download_pic(url):
    headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3970.5 Safari/537.36'}
    r=requests.get(url, headers=headers)
    soup=BeautifulSoup(r.text,'lxml')
    #get large div
    content=soup.find('div',class_='article')
    #print(content) #打印出class 为article标签下的内容
    #get all film pic
    images=content.find_all('img')#包含img的都选入images
    #get all film's name and downlad address
    pic_link_list=[image['src'] for image in images]
    pic_name_list=[image['alt'] for image in images]
    for picname, piclink in zip(pic_name_list,pic_link_list):
        urlretrieve(piclink, f'{download_path}/{picname}.jpg' )
        #  html=requests.get(piclink)  //法二、都测试成功
        #  with open(f'{download_path}/{picname}.jpg','wb') as f: #二进制字节流写入
        #      f.write(html.content)
    print(f'{url}所有电影图片下载完成')

def main():
    start_url=['https://movie.douban.com/top250']
    for i in range(0,11):
        start_url.append(f'https://movie.douban.com/top250?start={i*25}&filter=')
    for url in start_url:
        download_pic(url)

if __name__=='__main__':
    main()

运行结果

运行试试,结果为:

https://movie.douban.com/top250所有电影图片下载完成
https://movie.douban.com/top250?start=0&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=25&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=50&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=75&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=100&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=125&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=150&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=175&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=200&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=225&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=250&filter=所有电影图片下载完成

在这里插入图片描述

多线程

现在的run time

想要知道效率是否提升,就需要知道前后运行时间,从而进行对比!
想知道时间开销,就需要import time
在大for循环(关键代码,主要耗时代码)前加上:startTime=time.time()
for循环结束后加上endTime=time.time()
并打印出结果:print(f’run time={endTime-startTime}’)
运行结果:

https://movie.douban.com/top250所有电影图片下载完成
https://movie.douban.com/top250?start=0&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=25&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=50&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=75&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=100&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=125&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=150&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=175&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=200&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=225&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=250&filter=所有电影图片下载完成
run time=51.424378395080566

III 多线程优化

使用多线程池优化后,main方法代码如下:

from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED
def main():
    start_url=['https://movie.douban.com/top250']
    for i in range(0,11):
        start_url.append(f'https://movie.douban.com/top250?start={i*25}&filter=')
    startTime=time.time()
    # for url in start_url:
    #     download_pic(url)
    #使用线程池
    with ThreadPoolExecutor(max_workers=10) as executor:
        futures=[]
        for url in start_url:
            future=executor.submit(download_pic,url)
            futures.append(future)
        wait(futures, return_when=ALL_COMPLETED)
        
    endTime=time.time()
    print(f'run time={endTime-startTime}')
https://movie.douban.com/top250?start=175&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=50&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=0&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=100&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=25&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=250&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=200&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=150&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=75&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=125&filter=所有电影图片下载完成
https://movie.douban.com/top250?start=225&filter=所有电影图片下载完成
run time=20.880120754241943

时间快了一半还多
相较于单线程,可以简单理解
本来你打字若是计算机处理器就等待着你输入字符,把用户敲击键盘输入的速度和计算机的速度相比较,那将是很浪费的。
那计算机就可以处理qq的消息,音乐的播放等进程。而进程之内又可以有线程,使得多核CPU并发处理多线程,相较于在单核上跑进程,快速了许多。
线程也是小的进程、是OS中最小调度单位,当初学的操作系统也快忘光了。搬过来多线程无疑在此可以增大吞吐量,提高内存和处理器利用率,充分使计算机发挥了性能、
后续会继续深入的学习并理解Python中的多线程~到时再写blog

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不会写程序的程序员.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值