This commit is contained in:
2024-10-17 12:01:28 +08:00
commit e69a781072
3 changed files with 1283 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.ipynb_checkpoints

893
2. Python 基础.ipynb Normal file
View File

@@ -0,0 +1,893 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "9571b890-f74b-47da-9d17-89fd797fa493",
"metadata": {},
"source": [
"#### Jupyter Notebook 的基本操作\n",
"\n",
"- **创建新 Notebook**: 在 Jupyter 的主页上,点击右上角的 \"New\" 按钮,然后选择 \"Python 3\" 来创建一个新的 Notebook。\n",
"\n",
"- **运行单元格**: 选择一个单元格后,按 `Shift + Enter` 运行该单元格的内容。代码单元格会执行代码并显示输出。\n",
"\n",
"- **保存 Notebook**: 点击工具栏上的保存图标,或者使用快捷键 `Ctrl + S`Windows或 `Cmd + S`macOS。\n",
"\n",
"#### 注释的用法\n",
"\n",
"在编写代码时,注释是非常重要的,它们可以帮助你和其他人理解代码的目的和功能。注释不会被执行,只是作为说明存在。\n",
"\n",
"- **单行注释**: 使用 `#` 符号。所有在 `#` 后面的内容都会被视为注释。\n"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "02f18fde-16d9-45af-b3df-308d3d8bd9eb",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello, World!\n"
]
}
],
"source": [
"# 这是一个单行注释\n",
"print(\"Hello, World!\") # 这也是一个注释"
]
},
{
"cell_type": "markdown",
"id": "12b4e652-cb8b-4c2e-abb8-237b44dc1570",
"metadata": {},
"source": [
"### 代码块\n",
"\n",
"在 Jupyter Notebook 中,代码块是指一个代码单元格,它可以包含一段或多段 Python 代码。每个代码块都是一个独立的执行单元,你可以在其中编写代码、运行代码,并查看输出结果。以下是关于代码块及其输入输出的详细解释:\n",
"\n",
"- **代码单元格**: 在 Jupyter Notebook 中,代码块通常指的是代码单元格。你可以在代码单元格中输入 Python 代码,并通过运行该单元格来执行代码。\n",
"\n",
"- **运行代码块**: 选择一个代码单元格后,按 `Shift + Enter` 或点击工具栏上的 \"Run\" 按钮来运行代码。运行后,代码的输出会显示在单元格下方。\n",
"\n",
"### 输入和输出\n",
"\n",
"- **输入In**: 在 Jupyter Notebook 中,每个代码单元格的左侧会显示一个标签,如 `In [1]:`。这个标签表示这是第几个被执行的输入单元格。输入是指你在代码单元格中编写的代码。\n",
"\n",
"- **输出Out**: 当你运行一个代码单元格时,代码的执行结果会显示在单元格下方,这就是输出。输出可以是任何 Python 表达式的结果,如数值、字符串、列表、图表等。\n",
"\n",
"#### 示例"
]
},
{
"cell_type": "markdown",
"id": "d5bbfeb8-7507-47b6-8145-f9858462fd81",
"metadata": {},
"source": [
"- **输入**: 上述代码块中的所有代码行。\n",
"- **输出**: 运行代码块后,输出会显示为 `15`,这是最后一个表达式 `sum` 的结果。\n"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "b1a5270e-036a-4949-9f16-a2309831eba5",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"15"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 这是一个简单的代码块\n",
"a = 5\n",
"b = 10\n",
"sum = a + b\n",
"sum # 这个表达式的结果会作为输出显示"
]
},
{
"cell_type": "markdown",
"id": "a903b6a9-ca5c-4ddb-8d6e-b693e481ad6f",
"metadata": {},
"source": [
"### 多个输出\n",
"\n",
"在一个代码单元格中,只有最后一个表达式的结果会被自动显示为输出。如果你想在一个单元格中显示多个输出,可以使用 `print()` 函数。"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "c607e8f0-f191-40e1-bff0-6689f5e65639",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"5\n",
"10\n",
"15\n"
]
}
],
"source": [
"# 显示多个输出\n",
"print(a) # 输出 a 的值\n",
"print(b) # 输出 b 的值\n",
"print(sum) # 输出 sum 的值"
]
},
{
"cell_type": "markdown",
"id": "5affaf61-f01d-43d8-b807-ed872d659563",
"metadata": {},
"source": [
"---"
]
},
{
"cell_type": "markdown",
"id": "7ef935bd-0289-48c7-aa49-36750d5dcda2",
"metadata": {},
"source": [
"### 2. Python基础\n",
"#### 2.1 变量和数据类型"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "777ef098-4dd3-46ba-a642-45bc8eef3636",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'int'> <class 'float'> <class 'str'> <class 'bool'>\n"
]
}
],
"source": [
"# 整数\n",
"a = 10\n",
"# 浮点数\n",
"b = 20.5\n",
"# 字符串\n",
"c = \"Hello, World\"\n",
"# 布尔值\n",
"d = True\n",
"\n",
"print(type(a), type(b), type(c), type(d))"
]
},
{
"cell_type": "markdown",
"id": "55fcc17d-8684-4cda-9df3-a2256e17f81f",
"metadata": {},
"source": [
"#### 2.2 基本运算"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "13f3fadf-e16b-4b4e-91af-630cbc0bdf98",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"30.5 -10.5 205.0 0.4878048780487805\n"
]
}
],
"source": [
"# 算术运算\n",
"sum = a + b\n",
"difference = a - b\n",
"product = a * b\n",
"quotient = a / b\n",
"\n",
"print(sum, difference, product, quotient)"
]
},
{
"cell_type": "markdown",
"id": "62d1f7f3-cdcf-4a1f-84aa-e12e39ce59ad",
"metadata": {},
"source": [
"#### 2.3 列表 List\n",
"\n",
"列表list是一种非常常用的数据结构。它可以存储多个元素并且这些元素可以是不同类型的。下面是一些常用的列表操作及其解释"
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "b11a3e0c-4c4d-4d83-b231-cb57f841946f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"apple\n",
"cherry\n"
]
}
],
"source": [
"# 创建列表\n",
"fruits = [\"apple\", \"banana\", \"cherry\"]\n",
"print(fruits[0]) # 访问第一个元素\n",
"print(fruits[-1]) # 访问最后一个元素"
]
},
{
"cell_type": "markdown",
"id": "8cd1edab-0c73-4c74-a81e-4ec3af3e5010",
"metadata": {},
"source": [
"你可以使用 `append()` 方法在列表末尾添加元素"
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "8b65db8c-3013-4809-8027-8e543a9bd784",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['apple', 'banana', 'cherry', 'orange']"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 在末尾添加一个元素\n",
"fruits.append('orange')\n",
"# 现在 fruits 是 ['apple', 'blueberry', 'cherry', 'orange']\n",
"fruits"
]
},
{
"cell_type": "markdown",
"id": "70032e23-b96b-46fb-bd6f-6d4caea1719d",
"metadata": {},
"source": [
"你可以使用 `remove()` 方法删除指定的元素,或者使用 `pop()` 方法删除指定位置的元素(默认删除最后一个)。"
]
},
{
"cell_type": "code",
"execution_count": 30,
"id": "21e56204-b7c9-411f-8e54-3c55c9738e9c",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['apple', 'banana', 'cherry']"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 删除最后一个元素\n",
"last_fruit = fruits.pop()\n",
"# 现在 fruits 是 ['apple', 'blueberry', 'cherry']\n",
"fruits"
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "f4532754-3c89-40fa-bbe1-e52f47748a9b",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'orange'"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# last_fruit 是 'orange'\n",
"last_fruit"
]
},
{
"cell_type": "markdown",
"id": "474fd23f-e596-45c5-b400-c3d14826fc38",
"metadata": {},
"source": [
"你可以使用 `sort()` 方法对列表进行排序。"
]
},
{
"cell_type": "code",
"execution_count": 34,
"id": "785754cf-a820-4558-a61b-7045127f8436",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[1, 1, 2, 3, 4, 5, 9]"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"numbers = [3, 1, 4, 1, 5, 9, 2]\n",
"numbers.sort()\n",
"numbers"
]
},
{
"cell_type": "markdown",
"id": "f4efda3a-7b00-42a1-bbda-76bc8bc59425",
"metadata": {},
"source": [
"你可以使用切片操作来获取列表的一个子集。"
]
},
{
"cell_type": "code",
"execution_count": 36,
"id": "ced60078-2aaa-470c-8f65-4f03b8a9c5d4",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['apple', 'banana']\n",
"['banana', 'cherry']\n"
]
}
],
"source": [
"# 获取第一个和第二个元素\n",
"subset = fruits[0:2] # ['apple', 'cherry']\n",
"print(subset)\n",
"\n",
"# 获取从第二个元素到最后的所有元素\n",
"subset = fruits[1:] # ['cherry']\n",
"print(subset)"
]
},
{
"cell_type": "markdown",
"id": "d9e93e52-f799-4696-9c9f-d636075f50f2",
"metadata": {},
"source": [
"#### 2.4 字典 Dict\n",
"\n",
"字典dictionary是一种用于存储键值对key-value pairs的数据结构。字典中的每个键都是唯一的并且可以通过键快速访问对应的值。下面是一些常用的字典操作及其解释\n"
]
},
{
"cell_type": "code",
"execution_count": 37,
"id": "6f7a187a-9b2d-4a39-aef3-8e0d22af5670",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"25"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 创建一个空字典\n",
"my_dict = {}\n",
"\n",
"# 创建一个包含一些键值对的字典\n",
"person = {'name': 'Alice', 'age': 25, 'city': 'New York'}\n",
"\n",
"# 访问键为 'name' 的值\n",
"name = person['name'] # 'Alice'\n",
"\n",
"# 访问键为 'age' 的值\n",
"person['age'] # 25"
]
},
{
"cell_type": "code",
"execution_count": 38,
"id": "1c053ace-6613-4046-a269-9400edf8b28b",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'name': 'Alice', 'age': 25, 'city': 'New York', 'email': 'alice@example.com'}"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 添加一个新的键值对\n",
"person['email'] = 'alice@example.com'\n",
"person"
]
},
{
"cell_type": "code",
"execution_count": 39,
"id": "426d7a12-f908-47f0-b4ec-c37104fe890d",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'name': 'Alice', 'age': 25, 'email': 'alice@example.com'}"
]
},
"execution_count": 39,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 删除键为 'city' 的键值对\n",
"del person['city']\n",
"person"
]
},
{
"cell_type": "code",
"execution_count": 40,
"id": "e56c8bb6-1cb9-4866-9eac-4cd9111be196",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"True False\n"
]
}
],
"source": [
"# 检查 'name' 是否在字典中\n",
"has_name = 'name' in person # True\n",
"\n",
"# 检查 'city' 是否在字典中\n",
"has_city = 'city' in person # False\n",
"print(has_name, has_city)"
]
},
{
"cell_type": "markdown",
"id": "06d6079d-e554-4e65-ae86-026db05a94dd",
"metadata": {},
"source": [
"### 3. 控制结构\n",
"#### 3.1 条件语句"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "4e1b439a-59d2-4786-9d8e-78f0139a8782",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"a is less than or equal to b\n"
]
}
],
"source": [
"if a > b:\n",
" print(\"a is greater than b\")\n",
"else:\n",
" print(\"a is less than or equal to b\")"
]
},
{
"cell_type": "markdown",
"id": "d3c4da0f-69dd-4c5b-8296-5203cc3ced2b",
"metadata": {},
"source": [
"### 4. 函数"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "0a404d8d-b5f5-409e-924a-b6f644c9e64d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello, Alice!\n"
]
}
],
"source": [
"def greet(name):\n",
" return f\"Hello, {name}!\"\n",
"\n",
"print(greet(\"Alice\"))"
]
},
{
"cell_type": "markdown",
"id": "8014998b-9966-4211-a73b-2630783a26de",
"metadata": {},
"source": [
"### 5. 文本处理\n",
"#### 5.1 字符串操作\n",
"\n",
"Python提供了许多内置的方法来操作字符串。在这段代码中我们使用了 `split()` 方法。`split()` 是一个字符串方法,用于将字符串拆分为子字符串**列表**。默认情况下,它会在空白字符(如空格、制表符、换行符等)处分割字符串。\n",
"\n",
"列表是Python中的一种数据结构用于存储有序的元素集合。列表中的元素可以是任何数据类型并且列表是可变的即可以修改。在这段代码中`words = text.split()` 将返回一个列表,其中包含字符串 `text` 中的每个单词作为列表的元素。"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "12593239-b389-4081-a00f-f462fafc9b68",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['Python', 'is', 'great', 'for', 'text', 'processing']\n"
]
}
],
"source": [
"text = \"Python is great for text processing\"\n",
"words = text.split()\n",
"print(words)"
]
},
{
"cell_type": "markdown",
"id": "3f2a12b5-746b-45cf-9d41-62c129a6399f",
"metadata": {},
"source": [
"#### 5.2 字符串拼接\n",
"\n",
"在这段代码中我们展示了几种在Python中处理和格式化字符串的常用方法\n",
"\n",
"1. **字符串拼接**\n",
" - 使用加号 (`+`) 进行字符串拼接是最基本的方法。它将多个字符串连接在一起形成一个新的字符串。在示例中,`greeting`、`name` 和其他字符串通过加号连接,形成完整的问候语 `Hello, Alice!`。\n",
"\n",
"2. **`join` 方法**\n",
" - `join` 是一个字符串方法,用于将一个可迭代对象(如列表或元组)中的元素连接成一个字符串。每个元素之间用调用 `join` 的字符串作为分隔符。在示例中,`\" \".join(words)` 将列表 `words` 中的元素用空格连接,形成句子 `Python is fun`。\n",
"\n",
"3. **f-string格式化字符串**\n",
" - f-string 是Python 3.6引入的一种字符串格式化方法。它通过在字符串前加上字母 `f`,并在字符串中使用大括号 `{}` 包含变量名或表达式,来实现字符串的动态插值。在示例中,`f\"My name is {name} and I am {age} years old.\"` 使用了 f-string将变量 `name` 和 `age` 的值插入到字符串中,生成 `My name is Alice and I am 24 years old.`。"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "bc287103-f8bc-4c8e-8255-f5dfc679fc05",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello, Alice!\n",
"Python is fun\n",
"My name is Alice and I am 24 years old.\n"
]
}
],
"source": [
"# 使用加号拼接字符串\n",
"greeting = \"Hello\"\n",
"name = \"Alice\"\n",
"message = greeting + \", \" + name + \"!\"\n",
"print(message)\n",
"\n",
"# 使用join方法\n",
"words = [\"Python\", \"is\", \"fun\"]\n",
"sentence = \" \".join(words)\n",
"print(sentence)\n",
"\n",
"name = \"Alice\"\n",
"age = 24\n",
"\n",
"# 使用f-string\n",
"formatted_text = f\"My name is {name} and I am {age} years old.\"\n",
"print(formatted_text)"
]
},
{
"cell_type": "markdown",
"id": "e4b23e4c-ba67-4fe7-a95c-172ad71ab8b4",
"metadata": {},
"source": [
"#### 5.3 字符串查找和替换"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "94435998-7580-49fe-b812-b65a75258a54",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Position of 'great': 10\n",
"Python is excellent for text processing\n"
]
}
],
"source": [
"text = \"Python is great for text processing\"\n",
"\n",
"# 查找子字符串\n",
"position = text.find(\"great\")\n",
"print(f\"Position of 'great': {position}\")\n",
"\n",
"# 替换子字符串\n",
"new_text = text.replace(\"great\", \"excellent\")\n",
"print(new_text)"
]
},
{
"cell_type": "markdown",
"id": "75cc2929-68e4-484c-8489-e8079277014e",
"metadata": {},
"source": [
"#### 5.4 改变字符串大小写"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "021c7729-bf6d-4e60-a28c-fdf67b38ba1d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"python is great\n",
"PYTHON IS GREAT\n",
"Python Is Great\n"
]
}
],
"source": [
"text = \"Python is Great\"\n",
"\n",
"# 全部转换为小写\n",
"lower_text = text.lower()\n",
"print(lower_text)\n",
"\n",
"# 全部转换为大写\n",
"upper_text = text.upper()\n",
"print(upper_text)\n",
"\n",
"# 首字母大写\n",
"title_text = text.title()\n",
"print(title_text)"
]
},
{
"cell_type": "markdown",
"id": "0707ad7d-a6b4-496e-8f1f-d28d6b811bc3",
"metadata": {},
"source": [
"#### 5.5 去除空白字符"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "8ca8471c-46de-4495-ab53-9e9075764d0f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"|Python is great|\n",
"|Python is great |\n",
"| Python is great|\n"
]
}
],
"source": [
"text = \" Python is great \"\n",
"\n",
"# 去除两端空白字符\n",
"trimmed_text = text.strip()\n",
"print(f\"|{trimmed_text}|\")\n",
"\n",
"# 去除左侧空白字符\n",
"left_trimmed_text = text.lstrip()\n",
"print(f\"|{left_trimmed_text}|\")\n",
"\n",
"# 去除右侧空白字符\n",
"right_trimmed_text = text.rstrip()\n",
"print(f\"|{right_trimmed_text}|\")"
]
},
{
"cell_type": "markdown",
"id": "a749e823-4ab8-43d2-8da7-fc9b34f98ff1",
"metadata": {},
"source": [
"### 6. 循环控制\n",
"\n",
"在编程中循环是一种非常重要的结构它允许我们重复执行一段代码。Python 中有两种主要的循环结构:`for` 循环和 `while` 循环。接下来,我们将介绍如何使用这些循环,并结合 `range`、`list` 和 `dict` 进行讲解。\n",
"\n",
"#### 6.1 For 循环遍历列表\n",
"\n",
"列表(`list`)是 Python 中的一种数据结构,可以存储多个值。我们可以使用 `for` 循环来遍历列表中的每个元素。"
]
},
{
"cell_type": "code",
"execution_count": 41,
"id": "6645da47-7378-4446-af5b-c8eeeb8d6680",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"apple\n",
"banana\n",
"cherry\n"
]
}
],
"source": [
"# 定义一个列表\n",
"fruits = ['apple', 'banana', 'cherry']\n",
"\n",
"# 遍历列表\n",
"for fruit in fruits:\n",
" print(fruit)"
]
},
{
"cell_type": "markdown",
"id": "571bdd40-a16f-41c0-886b-227ae63752c7",
"metadata": {},
"source": [
"#### 6.3 For 循环遍历字典\n",
"\n",
"字典(`dict`)是一种键值对的数据结构。我们可以使用 `for` 循环来遍历字典的键和值。"
]
},
{
"cell_type": "code",
"execution_count": 42,
"id": "7d837497-6fb9-4d9c-a7ae-d7a2f06aae8d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"name Alice\n",
"age 25\n",
"city New York\n"
]
}
],
"source": [
"# 定义一个字典\n",
"person = {'name': 'Alice', 'age': 25, 'city': 'New York'}\n",
"\n",
"# 遍历字典的键\n",
"for key in person:\n",
" print(key, person[key])"
]
},
{
"cell_type": "markdown",
"id": "2a2f9289-ed6f-466b-b2e9-1b6deb64d7e6",
"metadata": {},
"source": [
"#### 6.4 While 循环\n",
"\n",
"`while` 循环在给定条件为 `True` 时重复执行一段代码。它适用于需要在循环中改变条件的情况。"
]
},
{
"cell_type": "code",
"execution_count": 44,
"id": "9d494e70-d499-4fa7-9454-af5677b7d275",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0\n",
"1\n",
"2\n",
"3\n",
"4\n"
]
}
],
"source": [
"# 使用 while 循环打印 0 到 4\n",
"count = 0\n",
"while count < 5:\n",
" print(count)\n",
" count += 1"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.9"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -0,0 +1,389 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "91b90d32-f565-46ee-9812-435e21f4cdfa",
"metadata": {},
"source": [
"# Python Selenium 爬虫教程\n",
"\n",
"Selenium 是一个强大的工具,可以用来自动化浏览器操作。它常被用于测试网页应用程序,但也可以用来抓取动态网页内容。在本教程中,我们将学习如何使用 Selenium 创建一个简单的爬虫。\n",
"\n",
"## 安装 Selenium\n",
"\n",
"在开始之前,你需要确保已经安装了 Selenium。你可以使用 pip 来安装:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cb1b2972-a128-4fe1-9b7c-d0a92b535cf2",
"metadata": {},
"outputs": [],
"source": [
"!pip install selenium"
]
},
{
"cell_type": "markdown",
"id": "b4fc3a34-d0b4-467a-bd14-a077930c3dd1",
"metadata": {},
"source": [
"## 打开网页"
]
},
{
"cell_type": "code",
"execution_count": 80,
"id": "6ffdca17-1501-406d-8d91-60f201d20d48",
"metadata": {},
"outputs": [],
"source": [
"from selenium import webdriver\n",
"from selenium.webdriver.common.by import By\n",
"import time\n",
"\n",
"# 创建一个新的 Chrome 浏览器会话\n",
"driver = webdriver.Chrome()\n",
"\n",
"# 让浏览器打开一个网页\n",
"driver.get('https://sou.chinanews.com/')\n"
]
},
{
"cell_type": "markdown",
"id": "3c2347be-d3fe-49ae-ba29-45c94131530b",
"metadata": {},
"source": [
"## 等待页面加载完成\n",
"\n",
"在使用 Selenium 进行网页自动化时,等待页面加载是一个常见的需求。除了使用简单的 `time.sleep()` 方法外Selenium 提供了更为智能和高效的等待方式。以下是几种常用的等待页面加载的方法:\n",
"\n",
"### 隐式等待Implicit Waits\n",
"\n",
"隐式等待是告诉 WebDriver 在查找元素时如果元素没有立即出现等待一段时间。WebDriver 会在指定的时间内不断地尝试查找元素。一般来说隐式等待是最好用的方法,它在查找到需要的元素后会立即响应,不会造成时间的浪费。\n",
"\n",
"隐式等待只要设置一次,之后对所有的元素查找都有效。"
]
},
{
"cell_type": "code",
"execution_count": 81,
"id": "44df02c7-ec43-466c-95ca-c5a5f6cdd81c",
"metadata": {},
"outputs": [],
"source": [
"driver.implicitly_wait(3) # 设置隐式等待时间为10秒"
]
},
{
"cell_type": "markdown",
"id": "a7aee1a6-50b5-4e2b-bb51-bed8833b4b34",
"metadata": {},
"source": [
"### 强制等待\n",
"\n",
"强制等待是指定程序运行到此处时,必须等待一定时间。强制等待通常用在动态页面的处理,或者等待一定时间降低速率以防被网站屏蔽。你需要明确指定暂停多少秒,这个时间比较难把控,容易造成时间浪费。\n",
"\n",
"强制等待必须每次查找元素前手动执行。"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "2421d6ca-5b50-41fa-8575-b1b39465e14c",
"metadata": {},
"outputs": [],
"source": [
"time.sleep(3)"
]
},
{
"cell_type": "markdown",
"id": "d2cebc62-c877-42f3-a80e-4aac03410e26",
"metadata": {},
"source": [
"## 操作浏览器\n",
"\n",
"以下代码使用了Selenium的`find_element`方法来查找网页中的元素。`By.XPATH`是查找元素的方式之一XPATH是一种用于在XML文档中查找信息的语言。在这里我们使用XPATH来定位网页中的一个输入框其XPATH为`'//*[@id=\"q\"]'`\n",
"\n",
"找到输入框之后,将字符串`'初音未来'`输入到输入框中。`send_keys`方法用于模拟键盘输入。"
]
},
{
"cell_type": "code",
"execution_count": 82,
"id": "7429d09e-0ca4-401c-adae-855cebb83f52",
"metadata": {},
"outputs": [],
"source": [
"input = driver.find_element(By.XPATH, '//*[@id=\"q\"]')\n",
"input.send_keys('初音未来')"
]
},
{
"cell_type": "markdown",
"id": "afeb2cfb-959e-486a-b538-71e6ac2eb09b",
"metadata": {},
"source": [
"接着继续找到搜索按钮,然后调用按钮的`click()`方法模拟鼠标点击事件。"
]
},
{
"cell_type": "code",
"execution_count": 83,
"id": "aa8cf6ae-233b-4ce4-af86-e0cd1bc0bb9f",
"metadata": {},
"outputs": [],
"source": [
"search = driver.find_element(By.XPATH, '/html/body/div[2]/form/div/button')\n",
"search.click()"
]
},
{
"cell_type": "markdown",
"id": "43687b93-3318-430f-ab57-7cfe03af22e8",
"metadata": {},
"source": [
"## 解析网页"
]
},
{
"cell_type": "code",
"execution_count": 74,
"id": "d873c6c9-c9ae-4212-94da-249d59fe69c2",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[['AI创作新风潮影视业拥抱AI新机遇',\n",
" 'https://www.chinanews.com.cn/cj/2023/08-28/10068093.shtml',\n",
" '进入新世纪,日本的初音未来、中国的洛天依等二次元虚拟歌手渐渐走进人们的视野,并在年轻人中掀起新的文化风潮。随着技术的革新,数字人的探索也不再只停留在二次元形象上,而是朝着超写实的人类形象发展。\\u3000\\u3000《神女杂货铺》的“果果”就是一个借助AI技术生成的超写实数字人。',\n",
" '2022-07-05 06:09:20'],\n",
" ['雨中跪地救人的“二次元小姐姐” 是位喜欢动漫的苏州医生',\n",
" 'https://www.chinanews.com.cn/sh/2023/07-26/10049675.shtml',\n",
" '张欣羽告诉记者她比较喜欢cosplay《初音未来》里面的角色所以在她的社交账号上经常能看到她梳着两条青色马尾的形象十分可爱。\\u3000\\u3000如今张欣羽工作日在医院上班周末会参加一些二次元的商演“主要是因为自己喜欢我喜欢舞台喜欢做自己喜欢的事情。',\n",
" '2022-07-05 06:09:20'],\n",
" ['首批AI克隆明星上线不只是娱乐业“躺赚”',\n",
" 'https://www.chinanews.com.cn/sh/2023/06-05/10019224.shtml',\n",
" '例如初音未来等虚拟偶像早已展示了新的数字技术对文娱行业的冲击而在元宇宙等概念成为风口之后借助AI技术实现的虚拟恋人等主打社交和精神陪伴的产品也蜂拥而至。\\u3000\\u3000此次引发争议的“AI克隆人”本质上依然属于数字虚拟人经济的一部分。',\n",
" '2022-07-05 06:09:20'],\n",
" ['“10后”的流行密语你能对上几个',\n",
" 'https://www.chinanews.com.cn/sh/2023/06-01/10017432.shtml',\n",
" '记者在采访中发现“10后”的音乐歌单呈现多元化特点无论是耳熟能详的经典音乐、当下最新的华语流行音乐还是二次元动漫歌曲、日韩流行歌曲、影视剧插曲、初音未来等虚拟偶像演唱的流行歌曲等都有对应的“10后”听众群。',\n",
" '2022-07-05 06:09:20'],\n",
" ['(经济观察)虚拟数字人“现身”各行各业 释放可观商业价值',\n",
" 'https://www.chinanews.com.cn/cj/2023/05-20/10010862.shtml',\n",
" '使用全息投影技术举办演唱会的虚拟歌手“初音未来”在洛杉矶、曼谷、上海、北京等多个城市进行了巡演游走在虚拟与现实边界的银发造型时尚博主“AYAYI”日常带货、看展甚至还拥有策展人身份俏皮少女“阿喜Angie”拿下多个品牌代言并参演了2023年网络春晚……随着虚拟数字人频繁“出圈”已有大量品牌向“',\n",
" '2022-07-05 06:09:20'],\n",
" ['网络热梗也能成为热门IP IP如何吸引Z世代',\n",
" 'https://www.chinanews.com.cn/cul/2022/12-15/9915069.shtml',\n",
" '虚拟偶像IP也逐渐在Z世代中风靡起来除初音未来、洛天依等大IP虚拟偶像“绊爱”以“超人工智能”形象跃入大众视野B站粉丝数约180万被网友评为“看似是人工智能其实是愚蠢的人工智障是前所未有的超科幻萌点。”\\u3000\\u3000文/本报记者陈斯',\n",
" '2022-07-05 06:09:20'],\n",
" ['玩具市场迎来多元需求 成年人“入坑”潮流玩具',\n",
" 'https://www.chinanews.com.cn/cj/2022/10-26/9880366.shtml',\n",
" '文创和虚拟偶像IP上榜最少其中文创IP中仅有头部的故宫文创、中国航天和三星堆上榜虚拟偶像中则只有元老级虚拟偶像IP初音未来上榜。',\n",
" '2022-07-05 06:09:20'],\n",
" ['越来越多场景应用 “数字人”走进大众生活',\n",
" 'https://www.chinanews.com.cn/cj/2022/09-07/9847169.shtml',\n",
" '中新网北京9月7日电 (中新财经 吴家驹)从“初音未来”到“洛天依”再到“嘉然”近年来“数字人”的概念渐渐走进我们的生活。在2022年服贸会上也出现了各具特色的“数字人”或可爱或端庄或活泼给参观者们留下深刻印象的同时也体现了“数字人”给未来生活带来的无限可能。',\n",
" '2022-07-05 06:09:20'],\n",
" ['爱的是“皮”还是“魂”?虚拟偶像凭什么“圈粉”',\n",
" 'https://www.chinanews.com.cn/cj/2022/07-05/9795608.shtml',\n",
" '这个由5名成员组成的虚拟偶像组合于2020年11月推出同早期“初音未来”等依托声库创作的数字化虚拟歌手不同其采用“中之人+皮套”模式短短一年时间全网粉丝超过2000万。',\n",
" '2022-07-05 06:09:20'],\n",
" ['唱歌跳舞的“皮套人”?这个千亿级生意没那么简单',\n",
" 'https://www.chinanews.com.cn/cj/2022/07-05/9795607.shtml',\n",
" '此前有外媒报道一名来自日本的男子和虚拟歌手初音未来在2018年举行了非正式婚礼而那时他们已经“交往”了10年。该男子表示和初音未来的关系让自己走出了抑郁他知道他的妻子——一个16岁的留着绿松石色头发的女孩——不是真正的人类但他对她的感情是真实的。',\n",
" '2022-07-05 06:09:20']]"
]
},
"execution_count": 74,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"news = []\n",
"for element in driver.find_elements(By.XPATH, '//*[@id=\"rightList\"]/div'):\n",
" title_element = element.find_element(By.XPATH, './/a')\n",
" title = title_element.text.strip()\n",
" #print(title)\n",
" url = title_element.get_attribute('href').strip()\n",
" #print(url)\n",
" desc = element.find_element(By.XPATH, 'following-sibling::*[1]//li[@class=\"news_content\"]').text.strip()\n",
" #print(desc)\n",
" #print('----------')\n",
" news.append([title, url, desc, date])\n",
"news"
]
},
{
"cell_type": "code",
"execution_count": 84,
"id": "05c4c70b-0a59-423c-ac6e-aa48344f1961",
"metadata": {},
"outputs": [],
"source": [
"# 点击所有标题\n",
"for link in driver.find_elements(By.XPATH, '//div[@class=\"news_title\"]/a'):\n",
" link.click()"
]
},
{
"cell_type": "code",
"execution_count": 53,
"id": "6737ce84-973f-4a7d-8d3a-b6a9afd57b5c",
"metadata": {},
"outputs": [],
"source": [
"# 跳转下一页\n",
"driver.find_element(By.XPATH, '//span[@class=\"thispage\"]/following-sibling::*[1]').click()"
]
},
{
"cell_type": "code",
"execution_count": 86,
"id": "f5e9b1b6-38b9-4c49-a13a-073a9046b1aa",
"metadata": {},
"outputs": [],
"source": [
"import requests\n",
"\n",
"url = 'https://sou.chinanews.com/search/news'\n",
"headers = {\n",
" 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',\n",
" 'Accept-Language': 'en-US,en;q=0.9',\n",
" 'Cache-Control': 'max-age=0',\n",
" 'Connection': 'keep-alive',\n",
" 'Content-Type': 'application/x-www-form-urlencoded',\n",
" 'Origin': 'https://sou.chinanews.com',\n",
" 'Referer': 'https://sou.chinanews.com/search/news',\n",
" 'Sec-Fetch-Dest': 'document',\n",
" 'Sec-Fetch-Mode': 'navigate',\n",
" 'Sec-Fetch-Site': 'same-origin',\n",
" 'Sec-Fetch-User': '?1',\n",
" 'Upgrade-Insecure-Requests': '1',\n",
" 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36',\n",
" 'sec-ch-ua': '\"Not?A_Brand\";v=\"99\", \"Chromium\";v=\"130\"',\n",
" 'sec-ch-ua-mobile': '?0',\n",
" 'sec-ch-ua-platform': '\"Linux\"',\n",
"}\n",
"\n",
"data = {\n",
" 'q': '初音未来', # 这里是 URL 编码后的查询字符串\n",
" 'searchField': 'all',\n",
" 'sortType': 'time',\n",
" 'dateType': 'all',\n",
" 'startDate': '',\n",
" 'endDate': '',\n",
" 'channel': 'all',\n",
" 'editor': '',\n",
" 'shouQiFlag': 'show',\n",
" 'pageNum': '1',\n",
"}\n",
"\n",
"response = requests.post(url, headers=headers, data=data)"
]
},
{
"cell_type": "code",
"execution_count": 110,
"id": "a28f7a58-1ad8-4f03-be9f-a412233fce48",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"标题: AI创作新风潮影视业拥抱AI新机遇\n",
"\n",
"段落:\n",
"\n",
"   前不久,一部以元宇宙为概念的国潮微短剧《神女杂货铺》在某视频平台播出,讲述了一个现代女孩穿越进游戏的奇幻故事。虽然这不是一部“爆款剧”,但剧中一位演员却引起大家的关注,那就是数字人“果果”。和以往的数字人相比,这一次,“果果”在影视作品中完成了她的出道首秀。不点破她的身份,观众甚至难以察觉她是“非人类”演员。\n",
"  近年来AIGC(人工智能生成内容)的浪潮正席卷与内容生产有关的各行各业,影视行业亦不例外。数字人“果果”在影视剧中的出演,是人工智能赋能影视产业的又一努力成果,让人们得以窥探人工智能在影视领域的最新应用与拓展。\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"  “AI演员”与真人演员难以分辨\n",
"  1982年日本动画《超时空要塞》以角色林明美为基础包装诞生了世界上第一位虚拟歌手。进入新世纪日本的初音未来、中国的洛天依等二次元虚拟歌手渐渐走进人们的视野并在年轻人中掀起新的文化风潮。随着技术的革新数字人的探索也不再只停留在二次元形象上而是朝着超写实的人类形象发展。\n",
"  《神女杂货铺》的“果果”就是一个借助AI技术生成的超写实数字人。“她是采用先进的AI技术换脸而成的虚拟演员看上去就好像是真的演员在出演这个角色一样。”《神女杂货铺》总制片人陈洪伟说。\n",
"  此前超写实数字人在影视作品并不罕见但大多通过CG(计算机动画)生成如《阿凡达》中的人物和《速度与激情7》中“复活”的保罗·沃克都是这类数字人。那么此前的数字人和“果果”这种超写实数字人有什么不同\n",
"  陈洪伟进一步介绍“这两者最大的区别在于此前影视作品里的数字人主要依托真人演员的外形通过CG技术进行分析、扫描、建模而“果果”这种超写实数字人完全没有真人的外形依托而是将AI算法与CG技术结合通过想象和理解来构建形象从而产生一个全新的、世界上本来并不存在的人。”\n",
"  2022年中国传媒大学媒体融合与传播国家重点实验室媒体大数据中心等发布的《中国虚拟数字人影响力指数报告》显示目前中国虚拟数字人在应用上主要有身份型(如真人虚拟分身)、服务型(如虚拟员工)、表演型(如虚拟偶像)三大类。虚拟演员并不在其列,可见在影视产业中应用并不广泛。\n",
"  2022年电视剧《二十不惑2》中使用了虚拟演员202作为一位超写实数字人202拥有与真人极度相似的外形但在剧中他仍然是一位“虚拟歌手”。随着技术迭代《神女杂货铺》中的“果果”拥有了专门为其定制的角色完成了推动故事发展的人物表演展示了自己的“演技”。\n",
"  “观看《神女杂货铺》时,观众普遍感到惊喜,有些人甚至分辨不出哪个是数字人演员,哪个是真人演员。”陈洪伟表示,“从技术上来讲,数字人毫无违和感地融入影视作品、甚至成为亮点已经不是问题,接下来需要完善的是艺术层面,比如人物审美、光影与剧集的融合、微表情的拿捏等。这些需要通过大量实践案例来打磨。”\n",
"  “数字电影”将走向“引擎电影”?\n",
"  《神女杂货铺》更像是陈洪伟的一个实验。\n",
"  身为80后陈洪伟大学一毕业就进入院线历任万达影业副总经理、腾讯影业副总裁从事电影制作发行方面的工作从一部电影的策划创意开发到投融资制作再到终端的营销与发行他都深度参与。他的“制片榜单”中不乏《十万个冷笑话》系列、《爱情公寓》《北京爱情故事》《滚蛋吧肿瘤君》等大家耳熟能详的影片。\n",
"  从业电影近20年陈洪伟坚信“未来影视行业的真正变革是因为技术的进一步发展”。2021年他又回到学校在北京电影学院攻读博士主要研究方向依然是他热爱的数字科技。他注意到新冠疫情让影视拍摄一度陷入停滞——人们无法外出却客观上让虚拟拍摄技术进入爆发式增长的状态。\n",
"  比如好莱坞的《曼达洛人》第一季就有超过50%的内容采用虚拟拍摄不需要外景演员们置身于一个半圆形的LED影棚中表演。不过陈洪伟认为虚拟拍摄只是一个过渡阶段虚拟制片的未来大可以更“激进”一些从“数字电影”转向“引擎电影”。\n",
"  他提出了未来电影的一个概念——AIEM (Artificial Intelligence Engine Movie)即AI引擎电影。所谓AI引擎电影即以数字人、虚拟场景、虚拟道具等数字资产为基础通过虚拟引擎生产电影人类导演只需告诉AI想要什么风格、多少时长等要求AI就会给出各种画面供选择。\n",
"  “AI引擎电影将来是可以替换掉一部分真人电影存在的。当现实世界中的数字资产积累得越丰富AI引擎电影就会越接近现实质感而且更加高效、便宜。”陈洪伟表示。在他看来这场技术革新将带来一个重大变革即个人会被赋予强大的影像生产力。\n",
"  事实上这一切已经在悄然发生。陈洪伟认识不少“片场都没去过、摄影机都没摸过”的年轻导演他们依靠引擎技术做出了不乏创意与风格的影片。比如B站上有个UP主是一名在校研究生他结合自己打游戏的经验自学编程制作了刘慈欣的《全频带阻塞干扰》的同名动画剧集基本都是个人独立完成。\n",
"  “虽然这只是一个电影爱好者的尝试,离真正的电影还有距离,但影视行业的未来,或许就在这些年轻人的探索中。”陈洪伟说。\n",
"  做“使用工具的人”还是“工具人”?\n",
"  毫无疑问,人工智能时代正在加速到来。影视从业者该如何应对?\n",
"  业内普遍认为现阶段AI参与影视制作的优势在于成本低和效率高但由于缺乏一站式的工具创作者使用起来仍有门槛全面改变行业还需要一些时间。\n",
"  “未来在影视行业AI不仅能够表演、拍摄还能写剧本。尽管如此它也只是一个工具创作者要做使用工具的人而不能做工具人。你不必会摄像、剪辑你只要有审美、有想象力、有创造力AI就能来帮你实现。”陈洪伟认为。在他看来创作分两种从零到一和从一到无穷AI解决的是从一到无穷的部分至于从零到一作为人的创造性不太可能被完全替代。\n",
"  目前一些创作者已经在用“人工+AI”的方式进行影视画面生产。曾执导《白蛇缘起》《新神榜哪吒重生》《新神榜杨戬》等动画电影的导演赵霁及其团队就尝试过使用一些开源AI图像生成模型。使用过程中他们发现AI能在极短的时间内提供一个大致接近构想的作品但当需要进一步精细化、风格化加工时目前的AI基本无法做到。\n",
"  赵霁还发现当前AI图片生成技术最具代表性的作品是动漫风格的各类人物其本质是AI经过大量用户的不断筛选而习得了广泛的审美标准。但是随着“生成—筛选”这一过程被不断重复人物开始逐渐呈现出审美同质化等问题。\n",
"  针对这一现象深耕人工智能领域多年的猎户星空董事长傅盛认为AI在追求最大用户群的一次认可时必定会选择满足大多数用户的普遍喜好因此要形成更具个人化的AI工具就必须进行长期的个性化训练使用更多的提示与指令不断细化要求。\n",
"  “电影作为创意产业其所应用的AI工具必然不宜采用某种通用模型而要走向垂直化、个性化模型。这也是未来人工智能发展的一个新契机涉及到对AI模型的差异化调整。”傅盛表示。\n",
"  面对AI目前全世界影视工作者都处在同一个技术起跑线上陈洪伟认为这是中国电影弯道超车难得的契机。在他的影视项目储备中就有与好莱坞制作人共同在AI技术应用领域进行合作的探索与尝试。“我们不能回避创新沉浸在旧有的舒适的体系框架内要自我突破全面拥抱AI带给我们的各种可能。”陈洪伟说。\n",
" \n",
"  郑 娜\n",
" \n",
"【编辑:陈文韬】 \n",
"\n",
" \n"
]
}
],
"source": [
"from lxml import etree\n",
"\n",
"response = requests.get('https://www.chinanews.com.cn/cj/2023/08-28/10068093.shtml', headers=headers)\n",
"response.encoding = 'utf-8'\n",
"# 解析HTML\n",
"html_tree = etree.HTML(response.text)\n",
"\n",
"# 使用XPath提取数据\n",
"titls = html_tree.xpath('//h1/text()') # 提取所有h1标签的文本\n",
"paragraphs = html_tree.xpath('//div[@class=\"left_zw\"]//text()') # 提取所有p标签的文本\n",
"\n",
"# 输出结果\n",
"print(\"标题:\", titls[0].strip())\n",
"\n",
"\n",
"print(\"\\n段落:\")\n",
"for paragraph in paragraphs:\n",
" print(paragraph)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.9"
}
},
"nbformat": 4,
"nbformat_minor": 5
}