爬虫 — 自动化爬虫 Selenium

news2024/11/18 13:45:08

目录

  • 一、介绍
  • 二、对比
  • 三、安装
  • 四、简单使用
  • 五、定位元素
    • 1、By.ID
    • 2、By.CLASS_NAME
    • 3、By.NAME
    • 4、By.TAG_NAM
    • 5、By.XPATH
  • 六、操作元素
    • 1、在输入框输入内容并搜索
    • 2、打开网站搜索音乐并播放
  • 七、Cookie 操作
    • 1、获取所有的 Cookie
    • 2、根据 Cookie 的 name 获取 Cookie
    • 3、删除某个 Cookie
    • 4、处理 Cookie
    • 5、案例
  • 八、Selenium 操作下拉菜单
  • 九、Selenium 鼠标行为链
    • 1、常用方法
    • 2、案例
  • 十、Selenium 切换页面与操作多窗口
    • 1、切换页面
    • 2、多窗口操作
  • 十一、Selenium 高级操作
    • 1、page_source:返回结构的源码
    • 2、find():在源码当中查找某个字符的存在
    • 3、By.LINK_TEXT:根据链接文本定位
    • 4、get_attribute():获取属性值
    • 5、.text:获取节点内容
  • 十二、设置无界面
  • 十三、页面等待
    • 1、强制等待
    • 2、隐式等待
    • 3、显示等待
  • 十四、案例

一、介绍

Selenium 爬取网页时,当前访问的 url 就是爬虫当中的目标 url,获取内容只要是页面上可见的,都可以爬取(可见即可爬)。

步骤

Selenium + 浏览器 + 浏览器驱动

1、导入

2、url(找动态 url,抓取到的数据是加密的)

3、获取内容,做解析

Selenium 是一个用于 Web 应用程序测试的工具,最初是为网站自动化测试而开发的,Selenium 可以直接运行在浏览器上,它支持所有主流的浏览器,可以接收指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏。

chromedriver 是一个驱动 Chrome 浏览器的驱动程序,使用它才可以驱动浏览器

针对不同的浏览器有不同的 driver,但 Chrome 的兼容性最好。

二、对比

Ajax:可以使用网页实现异步更新,可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

1、获取 Ajax 数据的方式

  • 直接分析 Ajax 调用的接口,然后通过代码请求这个接口。

  • 使用 Selenium + chromedriver 模拟浏览器行为获取数据。

2、获取 Ajax 数据方式对比

方式优点缺点
找数据接口直接可以请求到数据,代码量少,性能高分析接口比较复杂,尤其通过 js 混淆的接口,容易被发现是爬虫
Selenium直接模拟浏览器行为,浏览器能请求到的,使用 Selenium 也能请求到代码量多,性能低

三、安装

1、驱动下载地址

下载 Chrome 驱动

下载 Firefox 驱动

2、安装 Selenium 第三方库(建议指定版本安装)

pip install selenium==4.0.0a1

3、安装驱动(Chrome 的兼容性最好,建议安装 chromedriver)

  • 先确定浏览器版本号

在这里插入图片描述

在这里插入图片描述

  • 打开谷歌驱动下载地址

在这里插入图片描述

  • 版本号前面三位对应上就可以,最后一位建议选择版本小的

在这里插入图片描述

  • 按照电脑的系统来选择下载(如果电脑是 windows-64 位,选 win32 就行)

在这里插入图片描述

  • 驱动下载完成之后,将文件进行解压,复制到 chromedriver.exe 到 Python 解释器目录下

终端输入命令:where python 可以查看 Python 的安装目录

四、简单使用

# 导入模块,加载驱动
from selenium import webdriver
# 内置库
import time

# 加载驱动
drive = webdriver.Chrome()

# 窗口最大化
drive.maximize_window()

# 加载网站
drive.get('https://www.baidu.com')

# 代码停3秒再运行
time.sleep(3)

# 关闭当前的窗口
# drive.close()  # 要打开多个窗口,关闭的是当前的窗口

# 退出驱动
drive.quit()  # 关闭所有窗口,退出浏览器

五、定位元素

# 导入模块,加载驱动
from selenium import webdriver
# 定位元素
from selenium.webdriver.common.by import By

# 加载驱动
driver = webdriver.Chrome()

# 窗口最大化
driver.maximize_window()

# 加载网站
driver.get('https://www.baidu.com')

1、By.ID

根据 id 来查找定位元素。

# find_element 找一个元素,find_elements 找多个
el = driver.find_element(By.ID, 'kw')
# 返回的是一个元素对象
print(el)

2、By.CLASS_NAME

通过 class 属性值定位某个元素。

el = driver.find_element(By.CLASS_NAME, 's_ipt')
# 返回的是一个元素对象
print(el)

3、By.NAME

通过 name 属性查找定位某个元素。

el = driver.find_element(By.NAME, 'wd')
# 返回的是一个元素对象
print(el)

4、By.TAG_NAM

通过标签定位元素。

input_tag = driver.find_elements(By.TAG_NAME, 'input')
# find_elements 定位元素,返回的数据类型是 list
print(input_tag)

5、By.XPATH

通过 xpath 语法定位元素。

el = driver.find_element(By.XPATH, '//input[@id="kw"]')
# 返回的是一个元素对象
print(el)

六、操作元素

1、在输入框输入内容并搜索

# 内置库
import time
# 导入模块,加载驱动
from selenium import webdriver
# 定位元素
from selenium.webdriver.common.by import By

# 加载驱动
driver = webdriver.Chrome()

# 窗口最大化
driver.maximize_window()

# 加载网站
driver.get('https://www.baidu.com')

# 定位到元素
el = driver.find_element(By.ID, 'kw')

# 元素输入框里面输入值
el.send_keys('唐僧')

# 等待2秒
time.sleep(2)

# 点击元素
driver.find_element(By.ID, 'su').click()

# 清空内容
el.clear()

2、打开网站搜索音乐并播放

# 内置库
import time
# 导入模块,加载驱动
from selenium import webdriver
# 定位元素
from selenium.webdriver.common.by import By
# 操作键盘
from selenium.webdriver.common.keys import Keys

# 加载驱动
driver = webdriver.Chrome()

# 窗口最大化
driver.maximize_window()

# 加载网站
driver.get('https://music.163.com/')

# 搜索内容
driver.find_element(By.ID, 'srch').send_keys('愿')

# 按回车键
driver.find_element(By.ID, 'srch').send_keys(Keys.ENTER)

# 等待2秒
time.sleep(2)

# 网页里面嵌套了一个网页,要进入该网页才会获取对应的数据
driver.switch_to.frame('g_iframe')

# 播放按钮
driver.find_element(By.ID, 'song_2010214999').click()

七、Cookie 操作

1、获取所有的 Cookie

cookies = driver.get_cookies()

2、根据 Cookie 的 name 获取 Cookie

value = driver.get_cookie(name)

3、删除某个 Cookie

driver.delete_cookie('key')

4、处理 Cookie

# 导入模块,加载驱动
from selenium import webdriver

# 加载驱动
driver = webdriver.Chrome()

# 窗口最大化
driver.maximize_window()

# 加载网站
driver.get('https://www.baidu.com')

# 获取百度的 cookie
cookies = driver.get_cookies()

# 返回的 list,列表里面嵌套的字典
print(cookies)

'''
通过程序拿到的 cookie 与页面的是不一致,还需要做处理
只需要里面的两个字段值,name 和 value
BAIDUID_BFESS=F875E52E04E65B3748D8FDDE2E25399E; ZFY=idY6KuND2T0e6ROY1txjofI8Nvn4lb6hXiw:BN2mgeaA:C
'''
for cookie in cookies:
    print(cookie['name']+'='+ cookie['value'])

5、案例

模拟登录 qq 空间

# 内置库
import time
# 导入模块,加载驱动
from selenium import webdriver
# 定位元素
from selenium.webdriver.common.by import By

# 加载驱动
driver = webdriver.Chrome()

# 最大化窗口
driver.maximize_window()

# 加载网站
driver.get('https://i.qq.com/')

# 切换 iframe
driver.switch_to.frame('login_frame')

# 等待2秒
time.sleep(2)

# 点击头像进行登录,获取登录之后的 cookie
driver.find_element(By.ID, 'img_out_1234567890').click()

# 等待2秒
time.sleep(2)

# 获取 cookie
cookies = driver.get_cookies()

# 打印出的数据为列表
# print(cookies)

# 获取的 cookie 需要处理
li = []
for cookie in cookies:
    # 只需要每一组字典里面的 name value
    li.append(cookie['name']+'='+cookie['value'])
    # print(cookie)

# 处理好的 cookie
cookie = '; '.join(li)
print(cookie)

# 导入库
import requests

# 确定 url, 静态加载的
url = 'https://user.qzone.qq.com/1234567890'

# 设置请求头参数
head = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36',
    'cookie': cookie
}

# 发请求,获取响应
res = requests.get(url, headers=head)

# 获取响应内容
# print(res.text)

# 写入文件
with open('qq.html', 'w', encoding='utf-8') as f:
    f.write(res.text)

八、Selenium 操作下拉菜单

select 元素不能直接点击,因为点击后还需要选中元素,这时候 selenium 就专门为 select 标签提供了一个类。

from selenium.webdriver.support.ui import Select

将获取到的元素当成参数传到这个类中,创建这个对象后,就可以使用这个对象进行选择了。

案例

目标网站:https://news.sina.com.cn/

需求:选择娱乐版块,日期8号相关新闻

分析:

1、打开对应网站

2、点击下拉菜单,选择对应的版块内容

3、点击日期图标,选择的日期是8号

# 内置库
import time
# 导入模块,加载驱动
from selenium import webdriver
# 专门针对 Select 标签使用
from selenium.webdriver.support.ui import Select
# 定位元素
from selenium.webdriver.common.by import By

# 加载驱动
driver = webdriver.Chrome()

# 最大化窗口
driver.maximize_window()

# 加载网站
driver.get('https://news.sina.com.cn/')

# 解析,直接定位到 select 标签
el = driver.find_element(By.NAME, 'channel')
# print(el)

# 定位到娱乐的板块,实例化 select 对象
select_tag = Select(el)

# 定位下拉框
# 方法一
# select_tag.select_by_index(4)  # 下标从0开始的
# 方法二
# select_tag.select_by_value('ent')  # 根据 option 里面 value 属性定位的
# 方法三
select_tag.select_by_visible_text('娱乐')  # text 指的是文本

# 等待1秒
time.sleep(1)

# 定位日期
driver.find_element(By.NAME, 'date').click()

# 选择8号
driver.find_element(By.XPATH, '//div[@id="dataView"]/div/table/tbody/tr[2]/td[2]').click()

九、Selenium 鼠标行为链

页面中需要借助鼠标操作元素,那么这时候可以使用鼠标行为链类 ActionChains 来完成,比如现在要将鼠标移动到某个元素上并执行点击事件。

学习文档

1、常用方法

actions = ActionChains(driver)  # 实例化⼀个⿏标⾏为链的对象
actions.move_to_element(inputTag)  # 将⿏标移动到元素的中间
actions.send_keys_to_element(inputTag,'python')  # 将键发送到元素
actions.move_to_element(submitTag)  # 将⿏标移动到元素的中间
actions.context_click()  # 对元素执⾏上下⽂单击(右键单击)
actions.click(submitTag)  # 单击⼀个元素
actions.perform()  # 执⾏所有存储的操作
actions.lick_and_hold(element)  # 点击但不松开⿏标
actions.double_click(element)  # 双击

更多方法可参考

2、案例

目标网站:https://passport.vip.com/login?src=https%3A%2F%2Fwww.vip.com%2F

需求:

1、加载网站

2、切换登录方式

3、输入账号密码,勾选协议,点击登录案例

4、鼠标移动到对应的验证码元素上面

# 内置库
import time
# 导入模块,加载驱动
from selenium import webdriver
# 定位元素
from selenium.webdriver.common.by import By
# 导入鼠标行为链
from selenium.webdriver import ActionChains

# 加载驱动
driver = webdriver.Chrome()

# 最大化窗口
driver.maximize_window()

# 加载网站
driver.get('https://passport.vip.com/login?src=https%3A%2F%2Fwww.vip.com%2F')

# 等待2秒
time.sleep(2)

# 切换登录方式 —— 1、定位元素 2、点击
driver.find_element(By.XPATH, '//div[@class="c-tab-nav "]/div[2]').click()

# 等待0.5秒
time.sleep(0.5)

# 输入用户名
driver.find_element(By.ID, 'J_login_name').send_keys('3424234234')

# 输入密码
driver.find_element(By.ID, 'J_login_pwd').send_keys('34234242')

# 等待0.5秒
time.sleep(0.5)

# 勾选协议
inputs = driver.find_element(By.ID, 'J_login_agree')  # 定位到这个元素

# 通过 click 无法点击成功,可以采用 js 点击
driver.execute_script('arguments[0].click();', inputs)

# 登录
driver.find_element(By.ID, 'J_login_submit').click()

# 等待1秒
time.sleep(1)

# 定位图片
img = driver.find_element(By.CLASS_NAME, 'vipsc_qimg')

# 鼠标移动
actions = ActionChains(driver)
actions.move_to_element(img)  # 移动到目标位置

# 提交行为链
actions.perform()

十、Selenium 切换页面与操作多窗口

1、切换页面

# 内置库
import time
# 导入模块,加载驱动
from selenium import webdriver

# 加载驱动
driver = webdriver.Chrome()

# 最大化窗口
driver.maximize_window()

# 先模拟打开多个网站
driver.get('https://www.baidu.com')  # 百度
time.sleep(3)
driver.execute_script('window.open("https://www.douban.com/")')  # 豆瓣
time.sleep(3)
driver.execute_script('window.open("https://juejin.cn/")')  # 掘金
time.sleep(3)
driver.execute_script('window.open("https://cloud.tencent.com/developer/ask/sof/1237007")')  # 腾讯
time.sleep(3)

# 打印鼠标聚焦的 url
# print(driver.current_url)

# 切换窗口
driver.switch_to.window(driver.window_handles[-3])

'''
0:https://www.baidu.com
1:https://cloud.tencent.com/developer/ask/sof/1237007
2:https://juejin.cn/
3:https://www.douban.com/

-1:https://www.douban.com/
-2:https://juejin.cn/
-3:https://cloud.tencent.com/developer/ask/sof/1237007
'''

# 打印鼠标聚焦的 url
print(driver.current_url)

2、多窗口操作

# 内置库
import time
# 导入模块,加载驱动
from selenium import webdriver
# 定位元素
from selenium.webdriver.common.by import By

# 加载驱动
driver = webdriver.Chrome()

# 最大化窗口
driver.maximize_window()

# 加载网站
driver.get('https://juejin.cn/')

# 等待2秒
time.sleep(2)

# 定位第二篇文章
driver.find_element(By.XPATH, '//div[@class="entry-list list"]/li[2]').click()

# 等待1秒
time.sleep(1)

# 切换窗口
driver.switch_to.window(driver.window_handles[1])

# 获取 elements 内容
te = driver.page_source
print(te)

十一、Selenium 高级操作

1、page_source:返回结构的源码

# 内置库
import time
# 导入模块,加载驱动
from selenium import webdriver

# 加载驱动
driver = webdriver.Chrome()

# 最大化窗口
driver.maximize_window()

# 加载网站
driver.get('https://music.163.com/#/discover/toplist')

# 等待2秒
time.sleep(2)

# 切换到 iframe
driver.switch_to.frame('g_iframe')

# 等待2秒
time.sleep(2)

# 拿到的是 elements 里面的内容,xpath 直接做解析就可以了
print(driver.page_source)

2、find():在源码当中查找某个字符的存在

# 内置库
import time
# 导入模块,加载驱动
from selenium import webdriver
# 定位元素
from selenium.webdriver.common.by import By

# 加载驱动
driver = webdriver.Chrome()

# 最大化窗口
driver.maximize_window()

# 加载网站
driver.get('https://tieba.baidu.com/f?kw=%E8%8F%9C%E8%B0%B1&ie=utf-8&pn=11400')

# 等待2秒
time.sleep(2)

# # 获取网页源码
# html = driver.page_source
# # 打印源码
# print(html)
# # 看网页源码里是否存在下一页
# print(driver.page_source.find('下一页>'))
'''
如果没有查找到对应的字符,返回的是-1
如果查找到了,返回的是数字
'''

while True:
    # 判断源码里存在下一页时
    if driver.page_source.find('下一页>') != -1:
        # 点击下一页的按钮
        driver.find_element(By.CLASS_NAME, 'next').click()
        # 等待1秒
        time.sleep(1)
    # 源码里不存在下一页时,跳出循环
    else:
        print('已经是最后一页了')
        break

3、By.LINK_TEXT:根据链接文本定位

# 内置库
import time
# 导入模块,加载驱动
from selenium import webdriver
# 定位元素
from selenium.webdriver.common.by import By

# 加载驱动
driver = webdriver.Chrome()

# 最大化窗口
driver.maximize_window()

# 加载网站
driver.get('https://movie.douban.com/top250')

# 等待2秒
time.sleep(2)

# 获取网页源码
html = driver.page_source

# 等待1秒
time.sleep(1)

# 根据链接文本定位,点击‘后页>’
driver.find_element(By.LINK_TEXT, '后页>').click()

# 打印点击‘后页>’后的文本
print(driver.page_source)

4、get_attribute():获取属性值

# 内置库
import time
# 导入模块,加载驱动
from selenium import webdriver
# 定位元素
from selenium.webdriver.common.by import By

# 加载驱动
driver = webdriver.Chrome()

# 最大化窗口
driver.maximize_window()

# 加载网站
driver.get('https://movie.douban.com/top250')

# 等待2秒
time.sleep(2)

# 获取图片标签
img_tag = driver.find_element(By.XPATH, '//div[@class="pic"]/a/img')

# 获取属性值 —— 通过方法
print(img_tag.get_attribute('src'))

5、.text:获取节点内容

# 内置库
import time
# 导入模块,加载驱动
from selenium import webdriver
# 定位元素
from selenium.webdriver.common.by import By

# 加载驱动
driver = webdriver.Chrome()

# 最大化窗口
driver.maximize_window()

# 加载网站
driver.get('https://movie.douban.com/top250')

# 等待2秒
time.sleep(2)

# 获取文本内容
div_tag = driver.find_element(By.XPATH, '//div[@class="hd"]').text

# 打印文本内容
print(div_tag)

十二、设置无界面

# 内置库
import time
# 导入模块,加载驱动
from selenium import webdriver
# 定位元素
from selenium.webdriver.common.by import By

# 设置参数
options = webdriver.ChromeOptions()

# 设置无界面模式
options.add_argument('--headless')

# 传递参数
driver = webdriver.Chrome(options=options)

# 加载网站
driver.get('https://movie.douban.com/top250')

# 等待3秒
time.sleep(3)

# 获取图片标签
img_tag = driver.find_element(By.XPATH, '//div[@class="pic"]/a/img')

# 打印属性值
print(img_tag.get_attribute('src'))

十三、页面等待

1、强制等待

time.sleep(时间)

2、隐式等待

调用 driver.implicitly_wait ,针对所有元素,设置等待时间,如果等待时间内加载出来,代码继续往下走,等待时间以内不断刷新看元素是否加载出来,超出则报出异常。

# 导入模块,加载驱动
from selenium import webdriver
# 定位元素
from selenium.webdriver.common.by import By

# 加载驱动
driver = webdriver.Chrome()

# 加载网站
driver.get('https://www.baidu.com')

# 显示等待,针对的全局元素
driver.implicitly_wait(10)

# 10秒内出现代码继续往下走
driver.find_element(By.ID, 'kw').send_keys('python')

# 等待10秒不出现就会报错
driver.find_element(By.ID, 'kw1').send_keys('python')

3、显示等待

表明某个条件成立后才执行获取元素的操作,也可以在等待的时候指定一个最大的时间,如果超过这个时间那么就抛出一个异常。

# 显示等待,需要导入模块
# 导入 WebDriverWait 类
from selenium.webdriver.support.wait import WebDriverWait
# 导入 expected_conditions 模块并使用别名 EC
from selenium.webdriver.support import expected_conditions as EC
# 导入模块,加载驱动
from selenium import webdriver
# 定位元素
from selenium.webdriver.common.by import By

# 显示等待,需要导入模块
# 导入 WebDriverWait 类
from selenium.webdriver.support.wait import WebDriverWait
# 导入 expected_conditions 模块并使用别名 EC
from selenium.webdriver.support import expected_conditions as EC

# 加载驱动
driver = webdriver.Chrome()

# 加载网站
driver.get('https://www.baidu.com')

# 默认是0.5秒刷新一次
# 等待时间总共是10秒,每隔1秒刷新一次
# until 具体的条件内容
element = WebDriverWait(driver, 10, 1).until(
    # 判断元素是否加载出来
    EC.presence_of_element_located((By.ID, 'kw'))
)
element.send_keys('hello')

隐式等待针对的是全局元素,全局生效,代码简单,只用于查找元素。

显示等待有很多的判断条件,适用范围更广,只针对某一个元素。

十四、案例

目标网站: https://juejin.cn/

需求:爬取文章内容,保存为 txt 格式,文件名以文章标题命名

分析:

翻页方式:滑动滚动条进行加载内容

1、设置先滚动5次,先把下面的内容加载出来,获取元素

2、先获取所有 li 元素,遍历 li 元素,进行点击操作

# 内置库
import time
# 加载驱动
from selenium import webdriver
# 定位元素
from selenium.webdriver.common.by import By
# 正则
import re

class JuJin(object):

    # 定义初始化方法
    def __init__(self):
        # 实例属性
        # 加载驱动
        self.driver = webdriver.Chrome()
        # 窗口最大化
        self.driver.maximize_window()
        # 加载网站
        self.driver.get('https://juejin.cn/')

    # 解析数据
    def parse_html(self):
        # 等待2秒
        time.sleep(2)
        # 获取 li 里的所有数据
        lis = self.driver.find_elements(By.XPATH, '//div[@class="entry-list list"]/li')
        # 循环处理数据
        for li in lis:
            # 捕获异常
            try:
                # 等待2秒
                time.sleep(2)
                # 获取文章标题标签
                a = li.find_element(By.CLASS_NAME, 'title')
                # 点击标题标签进入详情页
                self.driver.execute_script('arguments[0].click();', a)
                # 切换窗口到内容页
                self.driver.switch_to.window(self.driver.window_handles[1])
                # 等待2秒
                time.sleep(2)
                # 获取标题标签
                title = self.driver.find_elements(By.CLASS_NAME, 'article-title')
                # 获取文章内容标签
                contents = self.driver.find_elements(By.XPATH, '//div[@class="markdown-body cache"]/p')
                # 判断标题是否是空列表,如果是空列表,说明文章是广告文章
                if not title:
                    # 获取标题标签
                    title = self.driver.find_elements(By.XPATH, '//a[@class="title"]/span')
                    # 获取文章内容标签
                    contents = self.driver.find_elements(By.XPATH, '//div[@class="markdown-body"]/p')
                # 获取标题文本
                titles = title[0].text
                # 正则表达式替换标题特殊字符
                titles = re.sub(r'[,?/<>!: ()|"]', '', titles)
                # 定义组装数据的变量
                s = ''
                # 获取数据为列表,需循环取出
                for i in contents:
                    # 组装数据
                    s += i.text + '\n'
                # 打印文章标题,内容
                # print(titles)
                # 保存数据
                self.save_data(titles, s)
                # 关闭当前窗口
                self.driver.close()
                # 切换窗口到列表页
                self.driver.switch_to.window(self.driver.window_handles[0])
                # 等待1秒
                time.sleep(1)
            except Exception as e:
                # 打印异常
                print(e)
                print("没有文章内容")
                # 关闭当前窗口
                self.driver.close()
                # 切换窗口到列表页
                self.driver.switch_to.window(self.driver.window_handles[0])

    # 保存数据
    def save_data(self, title, contents):
        # 创建 txt 文本文档
        with open(f'掘金/{title}.txt', 'w', encoding='utf-8') as f:
            # 文件写入
            f.write(contents)

    # 滚动方法
    def slide(self, height):
        # 滑动滚动条
        self.driver.execute_script(
            f'window.scrollTo(0,{height})'
        )

    # 处理主逻辑
    def main(self):
        # 获取窗口的高度
        heights = self.driver.get_window_size()['height']
        # 滑动次数
        page = 1
        # 滑动
        while page <= 5:
            self.slide(heights)
            # 加高度
            heights = heights + heights
            # 滑动次数+1
            page += 1
            # 等待1秒
            time.sleep(1)
        # 解析数据
        self.parse_html()

# 创建对象
data = JuJin()
# 调用 main 方法,开始执行主程序
data.main()

记录学习过程,欢迎讨论交流,尊重原创,转载请注明出处~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1018211.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《低代码指南》——低代码+AI,驱动企业数字资产保值增值

各位嘉宾,大家上午好!非常荣幸能借助钛媒体数字价值峰会这个平台跟大家交流。 了解奥哲的朋友知道,奥哲是国内第一家官宣聚焦低代码领域,并且以低代码定位获得融资的数字化企业。 过去两三年,低代码得到了飞速发展,我在此想跟各位分享下我们在过去实践过程中的一些发现,…

Java“牵手”速卖通商品列表页数据采集+速卖通商品价格数据排序,速卖通API接口申请指南

速卖通是阿里巴巴旗下的面向国际市场打造的跨境电商平台&#xff0c;被称为国际版淘宝&#xff0c;速卖通面向海外买家客户&#xff0c;通过支付宝国际账户进行担保交易&#xff0c;并使用国际物流渠道运输发货&#xff0c;是全球第三大英文在线购物网站。 速卖通商品列表数据…

【资源监视器】设备占用,强制弹出移动硬盘

设备占用&#xff0c;强制弹出移动硬盘 任务管理器中找到资源监视器 资源监视器&#xff1a;找到CPU 输入磁盘&#xff1a;如H: , 点击旁边的刷新 结束句柄 右键

CorelDRAW 2023怎么把图片转化为手绘素描风 简单几步轻松搞定

CorelDRAW 2023是一款非常好用的设计类软件&#xff0c;软件拥有非常多强大又好用的功能&#xff0c;可以帮助设计师快速创造出想要的效果&#xff0c;今天我们就来给大家介绍一下CDR的“素描”艺术笔触。它可以帮助用户快速将普通的图片快速转换成类似素描的风格&#xff0c;在…

AMD GPU 内核驱动分析(二)-gpu_sched

AMDGPU驱动模块的依赖关系如下图,gpu_sched.ko位于GPU驱动架构的中间层&#xff0c;主要负责对应用发送下来的渲染和计算等命令进行调度&#xff1a; 编译gpu_sched.ko 模块源码位于linux-x.x.xx/drivers/gpu/drm/scheduler下&#xff0c;通过CONFIG_DRM_SCHED项配置编译。从M…

更新至2021年,互联网相关指标数据

更新至2021年&#xff0c;互联网相关指标数据 1、来源&#xff1a;国家统计J和各省NJ 2、指标&#xff1a;域名数、网站数、网页数、互联网宽带接入端口、互联网宽带接入用户、城市宽带接入用户、移动互联网用户、移动互联网接入流量、联网上网人数 3、范围&#xff1a;31省…

四、日志编写 —— TinyWebServer

日志编写 —— TinyWebServer 一、 前言 上期已经写完lock类的编写。这期是日志的编写。 对于日志需要弄懂几个基本概念才可以更好的理解和编写日志。 什么是日志&#xff1f;常用的日志级别有哪些&#xff1f;日志的基本格式是什么&#xff1f;异步日志类刷新缓冲区的作用同…

虚幻4学习笔记(12)操控导入的角色、动画蓝图、播放蒙太奇和打包、角色重定向

虚幻4学习笔记 操控导入的角色设置鼠标旋转关掉动态模糊 动画蓝图、播放蒙太奇和打包角色走路奔跑动画shift 奔跑F 跳舞移动打断 跳舞 打包角色重定向姿势调整解决跑步 腿分太开隐藏剑 B站UP谌嘉诚课程&#xff1a;https://www.bilibili.com/video/BV164411Y732 操控导入的角色…

FreeSWITCH 1.10.10 简单图形化界面10 - 鼎兴FXO网关SIP注册公网IPPBX落地

FreeSWITCH 1.10.10 简单图形化界面10 - 鼎兴FXO网关SIP注册公网IPPBX落地 0、 界面预览1、创建一个话务台2、创建PBX SIP中继并设置呼入权限3、设置呼出规则4、设置分机呼出权限5、设置FXO 网关相关信息6、设置FXO网关端口组呼入号码7、设置FXO网关呼叫路由&#xff08;呼入及…

Eclipse搭建struts2框架

新建动态web项目&#xff1b; 输入项目名称&#xff1b; New Runtime后选择如下&#xff0c; 选择tomcat的安装目录&#xff1b; 然后如下&#xff0c;完成&#xff1b; 当前的目录结构如下&#xff1b;之前要配置好java环境&#xff1b; 如果创建项目时没有选中生成web.xml&am…

人工智能学习1

文章目录 人工智能人工智能的诞生人工智能的发展历程人工智能与机器学习的关系 机器学习机器学习的发展历程讨论机器学习的必要性机器学习的定义机器学习的三要素机器学习的基本概念作业 人工智能 人工智能的诞生 人工智能诞生于一群科学家想使用机器模拟人类思维或者人类智能…

黑马JVM总结(十二)

&#xff08;1&#xff09;五种引用_强软弱 实线箭头表示强引用&#xff0c;虚心线表示软弱虚终结器引用 在平时我们用的引用&#xff0c;基本都为强引用 &#xff0c;比如说创建一个对象通过运算符赋值给了一个变量&#xff0c;那么这个变量呢就强引用了刚刚的对象 强引用的…

Linux 磁盘挂载 磁盘卸载

挂载&#xff1a; 虚拟机中本来是没有光盘&#xff0c;但是有复刻的镜像文件&#xff0c;不影响我们挂载&#xff0c;当我们将镜像设备挂载到固定的目录下后&#xff0c;我们就可以通过访问目录&#xff0c;来查看镜像文件中的内容。 1. 创建挂载点&#xff1a; 一般虚拟设备上…

Java进化史:从Java 8到Java 17的语言特性全解析

文章目录 Java 8&#xff1a;引入Lambda表达式和Stream APILambda表达式Stream API Java 9&#xff1a;模块化系统模块Jigsaw项目 Java 10&#xff1a;局部变量类型推断Java 11&#xff1a;引入HTTP客户端HTTP客户端 Java 12&#xff1a;引入Switch表达式Switch表达式 Java 13到…

为什么学鸿蒙HarmonyOS——兴趣使然,HarmonyOS是一款面向万物互联时代的、全新的分布式操作系统

为什么学鸿蒙HarmonyOS 为什么学鸿蒙的诞生鸿蒙的未来鸿蒙OS典型案例鸿蒙是分布式操作系统总结参考学习资料 为什么学 兴趣使然&#xff0c;了解了一下鸿蒙系统的历史&#xff0c;是AIOT系统&#xff0c;是中国的未来的核心系统 鸿蒙&#xff1a;HarmonyOS是一款面向万物互联时…

antd a-list 添加分页

会分为三部分 template <a-list item-layout"horizontal" :data-source"localData" :pagination"{...paginationProps,current:currentPage}"><a-list-item slot"renderItem" slot-scope"item"><a-list-ite…

伪原创工具-好用的伪原创软件有哪些特征

在这个信息爆炸的时代&#xff0c;我们每天都要处理大量的文字信息&#xff0c;不管是在学校里写作业&#xff0c;还是在工作中处理文件。有时候&#xff0c;为了节省时间和精力&#xff0c;我们会考虑使用一些文章伪原创工具。 什么是文章伪原创&#xff1f; 让我们来明确一…

Netty(二)NIO-入门

Netty 入门 1. 概述 1.1 Netty Netty是一个异步的&#xff0c;基于事件驱动的网络应用框架&#xff0c;用于快速开发可维护&#xff0c;高性能的网络服务器和客户端 Cassandra&#xff0c;Spark&#xff0c;Hadoop&#xff0c;RocketMQ&#xff0c;ElasticSearch&#xff0c…

【小沐学写作】程序员必备技能:在线协作文档汇总

文章目录 1、简介2、微软Office在线文档2.1 功能简介2.2 使用费用2.3 用户体验 3、石墨文档3.1 功能简介3.2 使用费用 4、腾讯文档4.1 功能简介4.2 使用费用 5、语雀5.1 功能简介5.2 使用费用 6、飞书6.1 功能简介6.2 使用费用 7、印象笔记7.1 功能简介7.2 使用费用 结语 1、简…

解决xinput1_3.dll丢失的终极方法!快来尝试这4个方法吧!

在计算机系统中&#xff0c;DLL&#xff08;动态链接库&#xff09;是一个重要的组成部分&#xff0c;它们负责在程序和操作系统之间共享代码和数据。然而&#xff0c;当xinput1_3.dll丢失时&#xff0c;可能会导致一系列的问题&#xff0c;如系统运行缓慢、应用程序无法启动等…