4.6学习笔记

4.6学习笔记

一、概念

\1. 爬虫是否违法?
法不禁止即为许可
隐匿自己的身份(商业IP代理)
不要被目标网站举证有破坏动产行为
尽量遵守爬虫协议(robots.txt)
\2. 爬虫的分类和作用?
通用爬虫 —> 搜索引擎
定向爬虫 —> 有具体的爬取目标

对中小企业来说,数据一定是短板,要么花钱买数据,要么写爬虫
国家机器和很多的互联网产品做舆情监控基本也是通过网络爬虫来

\3. 爬虫怎么写?
抓取页面 —> requests / aiohttp
解析页面
- 正则表达式解析 —> re(regular expression)
~ compile() —> Pattern
search() / match() —> Match —> group()
findall() —> list
- XPath解析 —> lxml
右键菜单“检查” —> Copy —> Copy full XPath
- CSS选择器解析 —> beautifulsoup4 / pyquery
BeautifulSoup
- select():获取跟CSS选择器匹配的元素(列表)
- select_one():获取跟CSS选择器匹配的第一个元素 —> Tag
~ text:获取标签中的内容
attrs:字典,通过键值对的方式获取标签的属性值
保存数据
- CSV(逗号分隔值文件)—> csv~ reader / writer —> writerow()
- Excel —> xlrd / xlwt / openpyxl~ Workbook —> 工作簿 —> create_sheet()
—> Worksheet —> 工作表
—> cell(row, col, value) —> 单元格
\4. 如何抓取动态内容?
直接找到提供JSON数据的接口
- 浏览器开发者工具 —> Network —> XHR
- 专业的抓包工具 —> Charles / Fiddler / Wireshark
Selenium驱动浏览器获取动态内容
- 自动化测试工具
~ IDE
Remote Control
WebDriver:驱动浏览器模拟用户操作 —> 抓取到动态内容
- Chrome()
~ get():加载页面
隐式等待 / 显示等待
- implictly_wait(10):如果元素在10秒内没有出现就引发异常
- WebDriverWait(browser, 10) —> until() —> 指定等待条件
page_source:页面带动态内容的HTML代码
find_element_by_xxx() —> WebElement
find_elements_by_xxx() —> [WebElement]
- text:获取标签中的文本内容
- get_attribute():获取标签属性

\5. 如何实现并发(并行)编程?
并行:真正的同时进行,需要多CPU的支持
并发:可能不是真正的同时进行,但是通过快速的切换制造出并行的效果

线程:操作系统分配CPU的基本单位,最小的执行单元
进程:操作系统分配内存的基本单位,是程序在一组数据上的活动

通常我们启动一个程序,就启动了一个(或多个)进程,一个进程中又可以包含
一个或多个线程。

单线程(只有主线程,只有唯一的一个执行线索)
多线程 —> I/O密集型任务(爬虫)—> GIL(全局解释器锁)—> 无法使用多核特性
多进程 —> 计算密集型任务(音视频编解码、文件压缩、机器学习算法)
异步编程 —> I/O密集型任务(爬虫)—> 通过提高CPU利用率达到协作式并发

C —> CPython —> malloc() / free()
Java —> Jython
C# —> IronPython
Python —> PyPy

\6. easyocr —> ocr (optical character recognition)

pip install easyocr

二、实例

1)

import time

import requests
from selenium.webdriver import Chrome


def dowload_image(image_url):
    resp = requests.get(image_url)
    if resp.status_code == 200:
        filename = image_url[image_url.rfind('/') + 1:]
        try:
            with open(f'image360/{filename}', 'wb') as file:
                for data in resp.iter_content(512):
                    file.write(data)
        except OSError:
            pass


def main():
    browser = Chrome()
    browser.get('https://image.so.com/z?ch=beauty')

    for _ in range(5):
        # 让浏览器执行JavaScript代码
        browser.execute_script('window.scrollTo(0, window.scrollY + 1500)')
        time.sleep(0.5)

    # 隐式等待
    # 在使用find_xxx方法获取页面元素时,如果元素还没有出现,可以等待指定的时间,
    # 如果等待超时就引发异常,如果在指定的时间内获取到元素就返回对应的元素
    browser.implicitly_wait(10)
    # # 显示等待 ---> 创建一个等待对象
    # wait = WebDriverWait(browser, 10)
    # # 设置等待条件
    # wait.until(expected_conditions.presence_of_element_located(
    #     (By.CSS_SELECTOR, 'span.img > img')
    # ))
    image_tags = browser.find_elements_by_css_selector('span.img > img')
    # print(len(image_tags))
    start = time.time()
    for image_tag in image_tags:
        image_url = image_tag.get_attribute('src')
        dowload_image(image_url)
    end = time.time()
    print(f'下载耗时: {end - start:.3f}秒')
    browser.close()


if __name__ == '__main__':
    main()

2)

"""
装饰器:用一个函数去装饰另外一个函数或者类,为其提供额外的功能(横切关注功能)

装饰器实现了设计模式(前人总结的可重用的设计理念)中的代理模式(proxy pattern)

cross-concern
一等函数(一等公民):
    ~ 函数可以赋值给变量
    ~ 函数可以作为函数的参数
    ~ 函数可以作为函数的返回值
"""
import random
import time
from concurrent.futures.thread import ThreadPoolExecutor


# 装饰器的参数是被装饰的函数,返回值是带有装饰功能的函数
def record_time(func):

    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f'{func.__name__}执行时间:{end - start:.3f}秒')
        return result

    return wrapper


# download = record_time(download)
@record_time
def download(filename):
    print(f'开始下载{filename}.')
    time.sleep(random.randint(4, 6))
    print(f'{filename}下载完成.')


@record_time
def upload(filename):
    print(f'开始上传{filename}.')
    time.sleep(random.randint(5, 8))
    print(f'{filename}上传完成.')


@record_time
def main():
    # # 通过调用Thread类的构造器就可以创建线程对象,
    # # 通过指定target和args参数告诉线程启动后要执行的任务以及对应的参数
    # t1 = Thread(target=download, args=('Python从入门到住院', ))
    # t2 = Thread(target=download, args=('MySQL从删库到跑路', ))
    # t3 = Thread(target=upload, args=('数据分析从精通到放弃', ))
    # # 通过调用线程对象的start()方法启动线程
    # t1.start()
    # t2.start()
    # t3.start()
    # # 通过调用线程对象的join()方法等待线程结束
    # # 让主线程等待t1、t2、t3对应的线程执行结束
    # t3.join()
    # t2.join()
    # t1.join()
    # 创建和释放一个线程是有比较大的系统开销的,如果程序中频繁和释放线程,
    # 那么代码的性能也会受到影响,所以使用线程最佳的方式是提前创建线程池,
    # 线程池是一个容器,维持了若干个线程对象,需要线程的时候就从线程池中
    # 获取一个线程,用完了之后不释放而是归还给线程池,以便重复使用
    with ThreadPoolExecutor(max_workers=32) as pool:
        # 调用线程池对象的submit方法将任务交给线程池中的线程去执行
        # submit方法会返回Future对象(让你在将来可以获得线程的执行结果)
        pool.submit(download, 'Python从入门到住院')
        pool.submit(download, 'MySQL从删库到跑路')
        pool.submit(upload, '数据分析从精通到放弃')
        # 调用Future对象的result()方法可以在将来获取线程的执行结果
        # f1.result()
        # f2.result()
        # f3.result()


if __name__ == '__main__':
    main()

3)

import time
from concurrent.futures.process import ProcessPoolExecutor

import requests
from selenium.webdriver import Chrome


def dowload_image(image_url):
    resp = requests.get(image_url)
    if resp.status_code == 200:
        filename = image_url[image_url.rfind('/') + 1:]
        try:
            with open(f'image360/{filename}', 'wb') as file:
                for data in resp.iter_content(512):
                    file.write(data)
        except OSError:
            pass


def main():
    browser = Chrome()
    browser.get('https://image.so.com/z?ch=beauty')

    for _ in range(20):
        # 让浏览器执行JavaScript代码
        browser.execute_script('window.scrollTo(0, window.scrollY + 1500)')
        time.sleep(0.5)

    # 隐式等待
    # 在使用find_xxx方法获取页面元素时,如果元素还没有出现,可以等待指定的时间,
    # 如果等待超时就引发异常,如果在指定的时间内获取到元素就返回对应的元素
    browser.implicitly_wait(10)
    # # 显示等待 ---> 创建一个等待对象
    # wait = WebDriverWait(browser, 10)
    # # 设置等待条件
    # wait.until(expected_conditions.presence_of_element_located(
    #     (By.CSS_SELECTOR, 'span.img > img')
    # ))
    image_tags = browser.find_elements_by_css_selector('span.img > img')
    # print(len(image_tags))

    with ProcessPoolExecutor(max_workers=32) as pool:
        start = time.time()
        for image_tag in image_tags:
            image_url = image_tag.get_attribute('src')
            pool.submit(dowload_image, image_url)
    end = time.time()
    print(f'下载耗时: {end - start:.3f}秒')
    browser.close()


if __name__ == '__main__':
    main()

4)

"""
多线程和多进程的比较
"""
import concurrent.futures
import math

PRIMES = [
    1116281,
    1297337,
    104395303,
    472882027,
    533000389,
    817504243,
    982451653,
    112272535095293,
    112582705942171,
    112272535095293,
    115280095190773,
    115797848077099,
    1099726899285419
] * 5


def is_prime(n):
    """判断素数"""
    if n % 2 == 0:
        return n, False

    sqrt_n = int(math.floor(math.sqrt(n)))
    for i in range(3, sqrt_n + 1, 2):
        if n % i == 0:
            return n, False
    return n, True


def main():
    """主函数"""
    # with concurrent.futures.ThreadPoolExecutor() as pool:
    with concurrent.futures.ProcessPoolExecutor() as pool:
        futures = []
        for number in PRIMES:
            f = pool.submit(is_prime, number)
            futures.append(f)
        for f in futures:
            n, r = f.result()
            print(f'{n} is prime: {r}')
        # for number, prime in zip(PRIMES, pool.map(is_prime, PRIMES)):
        #     print('%d is prime: %s' % (number, prime))


if __name__ == '__main__':
    main()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CSDN IT狂飙上传的代码均可运行,功能ok的情况下才上传的,直接替换数据即可使用,小白也能轻松上手 【资源说明】 基于MATLAB实现的有限差分法实验报告用MATLAB中的有限差分法计算槽内电位;对比解析法和数值法的异同点;选取一点,绘制收敛曲线;总的三维电位图+使用说明文档 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2020b;若运行有误,根据提示GPT修改;若不会,私信博主(问题描述要详细); 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可后台私信博主; 4.1 期刊或参考文献复现 4.2 Matlab程序定制 4.3 科研合作 功率谱估计: 故障诊断分析: 雷达通信:雷达LFM、MIMO、成像、定位、干扰、检测、信号分析、脉冲压缩 滤波估计:SOC估计 目标定位:WSN定位、滤波跟踪、目标定位 生物电信号:肌电信号EMG、脑电信号EEG、心电信号ECG 通信系统:DOA估计、编码译码、变分模态分解、管道泄漏、滤波器、数字信号处理+传输+分析+去噪、数字信号调制、误码率、信号估计、DTMF、信号检测识别融合、LEACH协议、信号检测、水声通信 5、欢迎下载,沟通交流,互相学习,共同进步!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值