0%

爬虫

Playwright 是微软在 2020 年初开源的新一代自动化测试工具,它的功能类似于 Selenium、Pyppeteer 等,都可以驱动浏览器进行各种自动化操作。它的功能也非常强大,对市面上的主流浏览器都提供了支持,API 功能简洁又强大。虽然诞生比较晚,但是现在发展得非常火热。

1. Playwright 的特点

  • Playwright 支持当前所有主流浏览器,包括 Chrome 和 Edge(基于 Chromium)、Firefox、Safari(基于 WebKit) ,提供完善的自动化控制的 API。
  • Playwright 支持移动端页面测试,使用设备模拟技术可以使我们在移动 Web 浏览器中测试响应式 Web 应用程序。
  • Playwright 支持所有浏览器的 Headless 模式和非 Headless 模式的测试。
  • Playwright 的安装和配置非常简单,安装过程中会自动安装对应的浏览器和驱动,不需要额外配置 WebDriver 等。
  • Playwright 提供了自动等待相关的 API,当页面加载的时候会自动等待对应的节点加载,大大简化了 API 编写复杂度。

本节我们就来了解下 Playwright 的使用方法。

2. 安装

要使用 Playwright,需要 Python 3.7 版本及以上,请确保 Python 的版本符合要求。

要安装 Playwright,可以直接使用 pip3,命令如下:

1
pip3 install playwright

安装完成之后需要进行一些初始化操作:

1
playwright install

这时候 Playwrigth 会安装 Chromium, Firefox and WebKit 浏览器并配置一些驱动,我们不必关心中间配置的过程,Playwright 会为我们配置好。

具体的安装说明可以参考:https://setup.scrape.center/playwright。

安装完成之后,我们便可以使用 Playwright 启动 Chromium 或 Firefox 或 WebKit 浏览器来进行自动化操作了。

3. 基本使用

Playwright 支持两种编写模式,一种是类似 Pyppetter 一样的异步模式,另一种是像 Selenium 一样的同步模式,我们可以根据实际需要选择使用不同的模式。

我们先来看一个基本同步模式的例子:

1
2
3
4
5
6
7
8
9
10
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
for browser_type in [p.chromium, p.firefox, p.webkit]:
browser = browser_type.launch(headless=False)
page = browser.new_page()
page.goto('https://www.baidu.com')
page.screenshot(path=f'screenshot-{browser_type.name}.png')
print(page.title())
browser.close()

首先我们导入了 sync_playwright 方法,然后直接调用了这个方法,该方法返回的是一个 PlaywrightContextManager 对象,可以理解是一个浏览器上下文管理器,我们将其赋值为变量 p。

接着我们调用了 PlaywrightContextManager 对象的 chromium、firefox、webkit 属性依次创建了一个 Chromium、Firefox 以及 Webkit 浏览器实例,接着用一个 for 循环依次执行了它们的 launch 方法,同时设置了 headless 参数为 False。

注意:如果不设置为 False,默认是无头模式启动浏览器,我们看不到任何窗口。

launch 方法返回的是一个 Browser 对象,我们将其赋值为 browser 变量。然后调用 browser 的 new_page 方法,相当于新建了一个选项卡,返回的是一个 Page 对象,将其赋值为 page,这整个过程其实和 Pyppeteer 非常类似。接着我们就可以调用 page 的一系列 API 来进行各种自动化操作了,比如调用 goto,就是加载某个页面,这里我们访问的是百度的首页。接着我们调用了 page 的 screenshot 方法,参数传一个文件名称,这样截图就会自动保存为该图片名称,这里名称中我们加入了 browser_type 的 name 属性,代表浏览器的类型,结果分别就是 chromium, firefox, webkit。另外我们还调用了 title 方法,该方法会返回页面的标题,即 HTML 中 title 节点中的文字,也就是选项卡上的文字,我们将该结果打印输出到控制台。最后操作完毕,调用 browser 的 close 方法关闭整个浏览器,运行结束。

运行一下,这时候我们可以看到有三个浏览器依次启动并加载了百度这个页面,分别是 Chromium、Firefox 和 Webkit 三个浏览器,页面加载完成之后,生成截图、控制台打印结果就退出了。

这时候当前目录便会生成三个截图文件,都是百度的首页,文件名中都带有了浏览器的名称,如图所示:

控制台运行结果如下:

1
2
3
百度一下,你就知道
百度一下,你就知道
百度一下,你就知道

通过运行结果我们可以发现,我们非常方便地启动了三种浏览器并完成了自动化操作,并通过几个 API 就完成了截图和数据的获取,整个运行速度是非常快的,者就是 Playwright 最最基本的用法。

当然除了同步模式,Playwright 还提供异步的 API,如果我们项目里面使用了 asyncio,那就应该使用异步模式,写法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import asyncio
from playwright.async_api import async_playwright

async def main():
async with async_playwright() as p:
for browser_type in [p.chromium, p.firefox, p.webkit]:
browser = await browser_type.launch()
page = await browser.new_page()
await page.goto('https://www.baidu.com')
await page.screenshot(path=f'screenshot-{browser_type.name}.png')
print(await page.title())
await browser.close()

asyncio.run(main())

可以看到整个写法和同步模式基本类似,导入的时候使用的是 async_playwright 方法,而不再是 sync_playwright 方法。写法上添加了 async/await 关键字的使用,最后的运行效果是一样的。

另外我们注意到,这例子中使用了 with as 语句,with 用于上下文对象的管理,它可以返回一个上下文管理器,也就对应一个 PlaywrightContextManager 对象,无论运行期间是否抛出异常,它能够帮助我们自动分配并且释放 Playwright 的资源。

4. 代码生成

Playwright 还有一个强大的功能,那就是可以录制我们在浏览器中的操作并将代码自动生成出来,有了这个功能,我们甚至都不用写任何一行代码,这个功能可以通过 playwright 命令行调用 codegen 来实现,我们先来看看 codegen 命令都有什么参数,输入如下命令:

1
playwright codegen --help

结果类似如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Usage: npx playwright codegen [options] [url]

open page and generate code for user actions

Options:
-o, --output <file name> saves the generated script to a file
--target <language> language to use, one of javascript, python, python-async, csharp (default: "python")
-b, --browser <browserType> browser to use, one of cr, chromium, ff, firefox, wk, webkit (default: "chromium")
--channel <channel> Chromium distribution channel, "chrome", "chrome-beta", "msedge-dev", etc
--color-scheme <scheme> emulate preferred color scheme, "light" or "dark"
--device <deviceName> emulate device, for example "iPhone 11"
--geolocation <coordinates> specify geolocation coordinates, for example "37.819722,-122.478611"
--load-storage <filename> load context storage state from the file, previously saved with --save-storage
--lang <language> specify language / locale, for example "en-GB"
--proxy-server <proxy> specify proxy server, for example "http://myproxy:3128" or "socks5://myproxy:8080"
--save-storage <filename> save context storage state at the end, for later use with --load-storage
--timezone <time zone> time zone to emulate, for example "Europe/Rome"
--timeout <timeout> timeout for Playwright actions in milliseconds (default: "10000")
--user-agent <ua string> specify user agent string
--viewport-size <size> specify browser viewport size in pixels, for example "1280, 720"
-h, --help display help for command

Examples:

$ codegen
$ codegen --target=python
$ codegen -b webkit https://example.com

可以看到这里有几个选项,比如 -o 代表输出的代码文件的名称;—target 代表使用的语言,默认是 python,即会生成同步模式的操作代码,如果传入 python-async 就会生成异步模式的代码;-b 代表的是使用的浏览器,默认是 Chromium,其他还有很多设置,比如 —device 可以模拟使用手机浏览器,比如 iPhone 11,—lang 代表设置浏览器的语言,—timeout 可以设置页面加载超时时间。

好,了解了这些用法,那我们就来尝试启动一个 Firefox 浏览器,然后将操作结果输出到 script.py 文件,命令如下:

1
playwright codegen -o script.py -b firefox

这时候就弹出了一个 Firefox 浏览器,同时右侧会输出一个脚本窗口,实时显示当前操作对应的代码。

我们可以在浏览器中做任何操作,比如打开百度,然后点击输入框并输入 nba,然后再点击搜索按钮,浏览器窗口如下:

可以看见浏览器中还会高亮显示我们正在操作的页面节点,同时还显示了对应的选择器字符串 input[name="wd"],右侧的窗口如图所示:

在操作过程中,该窗口中的代码就实时变化,可以看到这里生成了我们一系列操作的对应代码,比如在搜索框中输入 nba,就对应如下代码:

1
page.fill("input[name=\"wd\"]", "nba")

操作完毕之后,关闭浏览器,Playwright 会生成一个 script.py 文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from playwright.sync_api import sync_playwright

def run(playwright):
browser = playwright.firefox.launch(headless=False)
context = browser.new_context()

# Open new page
page = context.new_page()

# Go to https://www.baidu.com/
page.goto("https://www.baidu.com/")

# Click input[name="wd"]
page.click("input[name=\"wd\"]")

# Fill input[name="wd"]
page.fill("input[name=\"wd\"]", "nba")

# Click text=百度一下
with page.expect_navigation():
page.click("text=百度一下")

context.close()
browser.close()

with sync_playwright() as playwright:
run(playwright)

可以看到这里生成的代码和我们之前写的示例代码几乎差不多,而且也是完全可以运行的,运行之后就可以看到它又可以复现我们刚才所做的操作了。

所以,有了这个功能,我们甚至都不用编写任何代码,只通过简单的可视化点击就能把代码生成出来,可谓是非常方便了!

另外这里有一个值得注意的点,仔细观察下生成的代码,和前面的例子不同的是,这里 new_page 方法并不是直接通过 browser 调用的,而是通过 context 变量调用的,这个 context 又是由 browser 通过调用 new_context 方法生成的。有读者可能就会问了,这个 context 究竟是做什么的呢?

其实这个 context 变量对应的是一个 BrowserContext 对象,BrowserContext 是一个类似隐身模式的独立上下文环境,其运行资源是单独隔离的,在做一些自动化测试过程中,每个测试用例我们都可以单独创建一个 BrowserContext 对象,这样可以保证每个测试用例之间互不干扰,具体的 API 可以参考 https://playwright.dev/python/docs/api/class-browsercontext

5. 移动端浏览器支持

Playwright 另外一个特色功能就是可以支持移动端浏览器的模拟,比如模拟打开 iPhone 12 Pro Max 上的 Safari 浏览器,然后手动设置定位,并打开百度地图并截图。首先我们可以选定一个经纬度,比如故宫的经纬度是 39.913904, 116.39014,我们可以通过 geolocation 参数传递给 Webkit 浏览器并初始化。

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
iphone_12_pro_max = p.devices['iPhone 12 Pro Max']
browser = p.webkit.launch(headless=False)
context = browser.new_context(
**iphone_12_pro_max,
locale='zh-CN',
geolocation={'longitude': 116.39014, 'latitude': 39.913904},
permissions=['geolocation']
)
page = context.new_page()
page.goto('https://amap.com')
page.wait_for_load_state(state='networkidle')
page.screenshot(path='location-iphone.png')
browser.close()

这里我们先用 PlaywrightContextManager 对象的 devices 属性指定了一台移动设备,这里传入的是手机的型号,比如 iPhone 12 Pro Max,当然也可以传其他名称,比如 iPhone 8,Pixel 2 等。

前面我们已经了解了 BrowserContext 对象,BrowserContext 对象也可以用来模拟移动端浏览器,初始化一些移动设备信息、语言、权限、位置等信息,这里我们就用它来创建了一个移动端 BrowserContext 对象,通过 geolocation 参数传入了经纬度信息,通过 permissions 参数传入了赋予的权限信息,最后将得到的 BrowserContext 对象赋值为 context 变量。

接着我们就可以用 BrowserContext 对象来新建一个页面,还是调用 new_page 方法创建一个新的选项卡,然后跳转到高德地图,并调用了 wait_for_load_state 方法等待页面某个状态完成,这里我们传入的 state 是 networkidle,也就是网络空闲状态。因为在页面初始化和加载过程中,肯定是伴随有网络请求的,所以加载过程中肯定不算 networkidle 状态,所以这里我们传入 networkidle 就可以标识当前页面和数据加载完成的状态。加载完成之后,我们再调用 screenshot 方法获取当前页面截图,最后关闭浏览器。

运行下代码,可以发现这里就弹出了一个移动版浏览器,然后加载了高德地图,并定位到了故宫的位置,如图所示:

输出的截图也是浏览器中显示的结果。

所以这样我们就成功实现了移动端浏览器的模拟和一些设置,其操作 API 和 PC 版浏览器是完全一样的。

6. 选择器

前面我们注意到 click 和 fill 等方法都传入了一个字符串,这些字符串有的符合 CSS 选择器的语法,有的又是 text= 开头的,感觉似乎没太有规律的样子,它到底支持怎样的匹配规则呢?下面我们来了解下。

传入的这个字符串,我们可以称之为 Element Selector,它不仅仅支持 CSS 选择器、XPath,Playwright 还扩展了一些方便好用的规则,比如直接根据文本内容筛选,根据节点层级结构筛选等等。

文本选择

文本选择支持直接使用 text= 这样的语法进行筛选,示例如下:

1
page.click("text=Log in")

这就代表选择文本是 Log in 的节点,并点击。

CSS 选择器

CSS 选择器之前也介绍过了,比如根据 id 或者 class 筛选:

1
2
page.click("button")
page.click("#nav-bar .contact-us-item")

根据特定的节点属性筛选:

1
2
page.click("[data-test=login-button]")
page.click("[aria-label='Sign in']")

CSS 选择器 + 文本

我们还可以使用 CSS 选择器结合文本值进行海选,比较常用的就是 has-text 和 text,前者代表包含指定的字符串,后者代表字符串完全匹配,示例如下:

1
2
page.click("article:has-text('Playwright')")
page.click("#nav-bar :text('Contact us')")

第一个就是选择文本中包含 Playwright 的 article 节点,第二个就是选择 id 为 nav-bar 节点中文本值等于 Contact us 的节点。

CSS 选择器 + 节点关系

还可以结合节点关系来筛选节点,比如使用 has 来指定另外一个选择器,示例如下:

1
page.click(".item-description:has(.item-promo-banner)")

比如这里选择的就是选择 class 为 item-description 的节点,且该节点还要包含 class 为 item-promo-banner 的子节点。

另外还有一些相对位置关系,比如 right-of 可以指定位于某个节点右侧的节点,示例如下:

1
page.click("input:right-of(:text('Username'))")

这里选择的就是一个 input 节点,并且该 input 节点要位于文本值为 Username 的节点的右侧。

XPath

当然 XPath 也是支持的,不过 xpath 这个关键字需要我们自行制定,示例如下:

1
page.click("xpath=//button")

这里需要在开头指定 xpath= 字符串,代表后面是一个 XPath 表达式。

关于更多选择器的用法和最佳实践,可以参考官方文档:https://playwright.dev/python/docs/selectors。

7. 常用操作方法

上面我们了解了浏览器的一些初始化设置和基本的操作实例,下面我们再对一些常用的操作 API 进行说明。

常见的一些 API 如点击 click,输入 fill 等操作,这些方法都是属于 Page 对象的,所以所有的方法都从 Page 对象的 API 文档查找就好了,文档地址:https://playwright.dev/python/docs/api/class-page。

下面介绍几个常见的 API 用法。

事件监听

Page 对象提供了一个 on 方法,它可以用来监听页面中发生的各个事件,比如 close、console、load、request、response 等等。

比如这里我们可以监听 response 事件,response 事件可以在每次网络请求得到响应的时候触发,我们可以设置对应的回调方法获取到对应 Response 的全部信息,示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
from playwright.sync_api import sync_playwright

def on_response(response):
print(f'Statue {response.status}: {response.url}')

with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.on('response', on_response)
page.goto('https://spa6.scrape.center/')
page.wait_for_load_state('networkidle')
browser.close()

这里我们在创建 Page 对象之后,就开始监听 response 事件,同时将回调方法设置为 on_response,on_response 对象接收一个参数,然后把 Response 的状态码和链接都输出出来了。

运行之后,可以看到控制台输出结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Statue 200: https://spa6.scrape.center/
Statue 200: https://spa6.scrape.center/css/app.ea9d802a.css
Statue 200: https://spa6.scrape.center/js/app.5ef0d454.js
Statue 200: https://spa6.scrape.center/js/chunk-vendors.77daf991.js
Statue 200: https://spa6.scrape.center/css/chunk-19c920f8.2a6496e0.css
...
Statue 200: https://spa6.scrape.center/css/chunk-19c920f8.2a6496e0.css
Statue 200: https://spa6.scrape.center/js/chunk-19c920f8.c3a1129d.js
Statue 200: https://spa6.scrape.center/img/logo.a508a8f0.png
Statue 200: https://spa6.scrape.center/fonts/element-icons.535877f5.woff
Statue 301: https://spa6.scrape.center/api/movie?limit=10&offset=0&token=NGMwMzFhNGEzMTFiMzJkOGE0ZTQ1YjUzMTc2OWNiYTI1Yzk0ZDM3MSwxNjIyOTE4NTE5
Statue 200: https://spa6.scrape.center/api/movie/?limit=10&offset=0&token=NGMwMzFhNGEzMTFiMzJkOGE0ZTQ1YjUzMTc2OWNiYTI1Yzk0ZDM3MSwxNjIyOTE4NTE5
Statue 200: https://p0.meituan.net/movie/da64660f82b98cdc1b8a3804e69609e041108.jpg@464w_644h_1e_1c
Statue 200: https://p0.meituan.net/movie/283292171619cdfd5b240c8fd093f1eb255670.jpg@464w_644h_1e_1c
....
Statue 200: https://p1.meituan.net/movie/b607fba7513e7f15eab170aac1e1400d878112.jpg@464w_644h_1e_1c

注意:这里省略了部分重复的内容。

可以看到,这里的输出结果其实正好对应浏览器 Network 面板中所有的请求和响应内容,和下图是一一对应的:

这个网站我们之前分析过,其真实的数据都是 Ajax 加载的,同时 Ajax 请求中还带有加密参数,不好轻易获取。

但有了这个方法,这里如果我们想要截获 Ajax 请求,岂不是就非常容易了?

改写一下判定条件,输出对应的 JSON 结果,改写如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
from playwright.sync_api import sync_playwright

def on_response(response):
if '/api/movie/' in response.url and response.status == 200:
print(response.json())

with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.on('response', on_response)
page.goto('https://spa6.scrape.center/')
page.wait_for_load_state('networkidle')
browser.close()

控制台输入如下:

1
2
3
{'count': 100, 'results': [{'id': 1, 'name': '霸王别姬', 'alias': 'Farewell My Concubine', 'cover': 'https://p0.meituan.net/movie/ce4da3e03e655b5b88ed31b5cd7896cf62472.jpg@464w_644h_1e_1c', 'categories': ['剧情', '爱情'], 'published_at': '1993-07-26', 'minute': 171, 'score': 9.5, 'regions': ['中国大陆', '中国香港']},
...
'published_at': None, 'minute': 103, 'score': 9.0, 'regions': ['美国']}, {'id': 10, 'name': '狮子王', 'alias': 'The Lion King', 'cover': 'https://p0.meituan.net/movie/27b76fe6cf3903f3d74963f70786001e1438406.jpg@464w_644h_1e_1c', 'categories': ['动画', '歌舞', '冒险'], 'published_at': '1995-07-15', 'minute': 89, 'score': 9.0, 'regions': ['美国']}]}

简直是得来全不费工夫,我们直接通过这个方法拦截了 Ajax 请求,直接把响应结果拿到了,即使这个 Ajax 请求有加密参数,我们也不用关心,因为我们直接截获了 Ajax 最后响应的结果,这对数据爬取来说实在是太方便了。

另外还有很多其他的事件监听,这里不再一一介绍了,可以查阅官方文档,参考类似的写法实现。

获取页面源码

要获取页面的 HTML 代码其实很简单,我们直接通过 content 方法获取即可,用法如下:

1
2
3
4
5
6
7
8
9
10
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto('https://spa6.scrape.center/')
page.wait_for_load_state('networkidle')
html = page.content()
print(html)
browser.close()

运行结果就是页面的 HTML 代码。获取了 HTML 代码之后,我们通过一些解析工具就可以提取想要的信息了。

页面点击

刚才我们通过示例也了解了页面点击的方法,那就是 click,这里详细说一下其使用方法。

页面点击的 API 定义如下:

1
page.click(selector, **kwargs)

这里可以看到必传的参数是 selector,其他的参数都是可选的。第一个 selector 就代表选择器,可以用来匹配想要点击的节点,如果传入的选择器匹配了多个节点,那么只会用第一个节点。

这个方法的内部执行逻辑如下:

  • 根据 selector 找到匹配的节点,如果没有找到,那就一直等待直到超时,超时时间可以由额外的 timeout 参数设置,默认是 30 秒。
  • 等待对该节点的可操作性检查的结果,比如说如果某个按钮设置了不可点击,那它会等待该按钮变成了可点击的时候才去点击,除非通过 force 参数设置跳过可操作性检查步骤强制点击。
  • 如果需要的话,就滚动下页面,将需要被点击的节点呈现出来。
  • 调用 page 对象的 mouse 方法,点击节点中心的位置,如果指定了 position 参数,那就点击指定的位置。

click 方法的一些比较重要的参数如下:

  • click_count:点击次数,默认为 1。
  • timeout:等待要点击的节点的超时时间,默认是 30 秒。
  • position:需要传入一个字典,带有 x 和 y 属性,代表点击位置相对节点左上角的偏移位置。
  • force:即使不可点击,那也强制点击。默认是 False。

具体的 API 设置参数可以参考官方文档:https://playwright.dev/python/docs/api/class-page/#pageclickselector-kwargs。

文本输入

文本输入对应的方法是 fill,API 定义如下:

1
page.fill(selector, value, **kwargs)

这个方法有两个必传参数,第一个参数也是 selector,第二个参数是 value,代表输入的内容,另外还可以通过 timeout 参数指定对应节点的最长等待时间。

获取节点属性

除了对节点进行操作,我们还可以获取节点的属性,方法就是 get_attribute,API 定义如下:

1
page.get_attribute(selector, name, **kwargs)

这个方法有两个必传参数,第一个参数也是 selector,第二个参数是 name,代表要获取的属性名称,另外还可以通过 timeout 参数指定对应节点的最长等待时间。

示例如下:

1
2
3
4
5
6
7
8
9
10
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto('https://spa6.scrape.center/')
page.wait_for_load_state('networkidle')
href = page.get_attribute('a.name', 'href')
print(href)
browser.close()

这里我们调用了 get_attribute 方法,传入的 selector 是 a.name,选定了 class 为 name 的 a 节点,然后第二个参数传入了 href,获取超链接的内容,输出结果如下:

1
/detail/ZWYzNCN0ZXVxMGJ0dWEjKC01N3cxcTVvNS0takA5OHh5Z2ltbHlmeHMqLSFpLTAtbWIx

可以看到对应 href 属性就获取出来了,但这里只有一条结果,因为这里有个条件,那就是如果传入的选择器匹配了多个节点,那么只会用第一个节点。

那怎么获取所有的节点呢?

获取多个节点

获取所有节点可以使用 query_selector_all 方法,它可以返回节点列表,通过遍历获取到单个节点之后,我们可以接着调用单个节点的方法来进行一些操作和属性获取,示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto('https://spa6.scrape.center/')
page.wait_for_load_state('networkidle')
elements = page.query_selector_all('a.name')
for element in elements:
print(element.get_attribute('href'))
print(element.text_content())
browser.close()

这里我们通过 query_selector_all 方法获取了所有匹配到的节点,每个节点对应的是一个 ElementHandle 对象,然后 ElementHandle 对象也有 get_attribute 方法来获取节点属性,另外还可以通过 text_content 方法获取节点文本。

运行结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/detail/ZWYzNCN0ZXVxMGJ0dWEjKC01N3cxcTVvNS0takA5OHh5Z2ltbHlmeHMqLSFpLTAtbWIx
霸王别姬 - Farewell My Concubine
/detail/ZWYzNCN0ZXVxMGJ0dWEjKC01N3cxcTVvNS0takA5OHh5Z2ltbHlmeHMqLSFpLTAtbWIy
这个杀手不太冷 - Léon
/detail/ZWYzNCN0ZXVxMGJ0dWEjKC01N3cxcTVvNS0takA5OHh5Z2ltbHlmeHMqLSFpLTAtbWIz
肖申克的救赎 - The Shawshank Redemption
/detail/ZWYzNCN0ZXVxMGJ0dWEjKC01N3cxcTVvNS0takA5OHh5Z2ltbHlmeHMqLSFpLTAtbWI0
泰坦尼克号 - Titanic
/detail/ZWYzNCN0ZXVxMGJ0dWEjKC01N3cxcTVvNS0takA5OHh5Z2ltbHlmeHMqLSFpLTAtbWI1
罗马假日 - Roman Holiday
/detail/ZWYzNCN0ZXVxMGJ0dWEjKC01N3cxcTVvNS0takA5OHh5Z2ltbHlmeHMqLSFpLTAtbWI2
唐伯虎点秋香 - Flirting Scholar
/detail/ZWYzNCN0ZXVxMGJ0dWEjKC01N3cxcTVvNS0takA5OHh5Z2ltbHlmeHMqLSFpLTAtbWI3
乱世佳人 - Gone with the Wind
/detail/ZWYzNCN0ZXVxMGJ0dWEjKC01N3cxcTVvNS0takA5OHh5Z2ltbHlmeHMqLSFpLTAtbWI4
喜剧之王 - The King of Comedy
/detail/ZWYzNCN0ZXVxMGJ0dWEjKC01N3cxcTVvNS0takA5OHh5Z2ltbHlmeHMqLSFpLTAtbWI5
楚门的世界 - The Truman Show
/detail/ZWYzNCN0ZXVxMGJ0dWEjKC01N3cxcTVvNS0takA5OHh5Z2ltbHlmeHMqLSFpLTAtbWIxMA==
狮子王 - The Lion King

获取单个节点

获取单个节点也有特定的方法,就是 query_selector,如果传入的选择器匹配到多个节点,那它只会返回第一个节点,示例如下:

1
2
3
4
5
6
7
8
9
10
11
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto('https://spa6.scrape.center/')
page.wait_for_load_state('networkidle')
element = page.query_selector('a.name')
print(element.get_attribute('href'))
print(element.text_content())
browser.close()

运行结果如下:

1
2
/detail/ZWYzNCN0ZXVxMGJ0dWEjKC01N3cxcTVvNS0takA5OHh5Z2ltbHlmeHMqLSFpLTAtbWIx
霸王别姬 - Farewell My Concubine

可以看到这里只输出了第一个匹配节点的信息。

网络劫持

最后再介绍一个实用的方法 route,利用 route 方法,我们可以实现一些网络劫持和修改操作,比如修改 request 的属性,修改 response 响应结果等。

看一个实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from playwright.sync_api import sync_playwright
import re

with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()

def cancel_request(route, request):
route.abort()

page.route(re.compile(r"(\.png)|(\.jpg)"), cancel_request)
page.goto("https://spa6.scrape.center/")
page.wait_for_load_state('networkidle')
page.screenshot(path='no_picture.png')
browser.close()

这里我们调用了 route 方法,第一个参数通过正则表达式传入了匹配的 URL 路径,这里代表的是任何包含 .png.jpg 的链接,遇到这样的请求,会回调 cancel_request 方法处理,cancel_request 方法可以接收两个参数,一个是 route,代表一个 CallableRoute 对象,另外一个是 request,代表 Request 对象。这里我们直接调用了 route 的 abort 方法,取消了这次请求,所以最终导致的结果就是图片的加载全部取消了。

观察下运行结果,如图所示:

可以看到图片全都加载失败了。

这个设置有什么用呢?其实是有用的,因为图片资源都是二进制文件,而我们在做爬取过程中可能并不想关心其具体的二进制文件的内容,可能只关心图片的 URL 是什么,所以在浏览器中是否把图片加载出来就不重要了。所以如此设置之后,我们可以提高整个页面的加载速度,提高爬取效率。

另外,利用这个功能,我们还可以将一些响应内容进行修改,比如直接修改 Response 的结果为自定义的文本文件内容。

首先这里定义一个 HTML 文本文件,命名为 custom_response.html,内容如下:

1
2
3
4
5
6
7
8
9
<!DOCTYPE html>
<html>
<head>
<title>Hack Response</title>
</head>
<body>
<h1>Hack Response</h1>
</body>
</html>

代码编写如下:

1
2
3
4
5
6
7
8
9
10
11
12
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()

def modify_response(route, request):
route.fulfill(path="./custom_response.html")

page.route('/', modify_response)
page.goto("https://spa6.scrape.center/")
browser.close()

这里我们使用 route 的 fulfill 方法指定了一个本地文件,就是刚才我们定义的 HTML 文件,运行结果如下:

可以看到,Response 的运行结果就被我们修改了,URL 还是不变的,但是结果已经成了我们修改的 HTML 代码。

所以通过 route 方法,我们可以灵活地控制请求和响应的内容,从而在某些场景下达成某些目的。

8. 总结

本节介绍了 Playwright 的基本用法,其 API 强大又易于使用,同时具备很多 Selenium、Pyppeteer 不具备的更好用的 API,是新一代 JavaScript 渲染页面的爬取利器。

本节代码:https://github.com/Python3WebSpider/PlaywrightTest。

Other

以往各大云服务商在双十一大促都会推出很多活动,例如前几年会有 1核2G1M 69 元这类新用户活动。没想到今年腾讯云活动相当猛,2核CPU+4G内存+8M带宽首年70 块钱!如果按 3 年买,也只是 198 元,要知道平时买这样的服务器,怎么说也要 1000+ 元。

如果你不懂如何操作云服务器,可以观看【社区公开课】视频-工程师必知必会的 Linux 云服务器

活动主会场

除此之外,腾讯云那边联系到社区一起办活动,给了一部分奖励,大家从社区链接购买他们本次活动产品的可以找社区小助手返现金,具体活动规则如下:

1、腾讯云新用户 (个人或企业)购买金额大于 100 元,社区将按购买金额的 5% 进行返现;
2、腾讯云新用户 (个人或企业)购买金额大于 50 、小于 100 元,社区一次性返现 5 元;
3、腾讯云新用户 (个人或企业)购买金额大于 1000 元,社区将按购买金额的 10% 进行返现;
4、腾讯云老用户 (个人或企业)购买金额大于 300 元,社区将按购买金额的 5% 进行返现;

5、如果购买多个产品,请在同一个订单中结算(即一次性购买);

社区专属活动链接(可点击此处跳转也可复制下方地址):

1
https://cloud.tencent.com/act/double11?spread_hash_key=92518f4cf8e4cb326251fe0f7537bc23&cps_key=f31586a82039422aee085aac372348bd

attachmentId-956

活动截止时间:活动截止日期为 2021-11-30 日 12:00:00;

奖励是否叠加:不叠加;

返现发放时间:预计 30 个工作日内;

返现发放方式:个人微信/支付宝打款、企业对公打款;

⚠️ 活动参与要求 :必须是穿甲兵技术社区用户;通过社区提供的链接前往腾讯云双十一活动主会场,购买主会场中推荐的腾讯云产品;活动 COOKIE 持续 30 分钟,点击后如果还在观察活动、未购买的朋友,在购买前请再点击一次社区专属活动链接 ,以免后续在后台查询不到订单信息,也就拿不到返现。

参与活动的朋友,请联系穿甲兵小助手 (微信 elasticworm )计算返现;

社区补贴活动刚开始 2 天,已经有 150 多人参加了,他们都联系了小助手要补贴,火热火热的!错过了这次大促活动,以后买服务器可贵了

参与名单

除了云服务器活动给力之外,新用户注册 .com 域名首年也只需要 1 元!

腾讯云还为大家准备了代金券,简直省到家了

代金券

⚠️注意:社区云产品规则、适用范围等请阅读腾讯云相关文档;

Python

前些天我发起了一个投票,让大家帮忙为 《Python3 网络爬虫开发实战(第二版)》选几个封面,大家也纷纷出谋划策。

其实第二版和第一版整体差别不大,这次设计主要就是换个封面的图片,然后加一个第二版的标识就好了。

之前第一版的封面是这样的:

但这个蜘蛛我觉得还有改进的空间,于是就想换一个。

然后我就自己设计了一个,然后同时设计师也设计了一个,最后出来这么几个版本:

当时就是拿不定主意,然后就发起了一个投票活动,邀请群里的各个小伙伴们来投票。

大家参与也很积极,三百多个人参与了投票,结果是这样的:

当时选项一就是刚才设计的第一张图片,选项二和三就是刚才设计的第二张图片,只是背景元素稍微换了换。

结果大家几乎清一色的都投了选项三。

但其实我对这个选项的蜘蛛不太满意,它长这样:

我就感觉,这怎么跟闹着玩似的?而且腿也太细了吧,也没点过渡和弯折,比较奇怪。但是第一个设计的根据大家的反馈,说蜘蛛的形态比较吓人,还有的人说看起来不像蜘蛛,像章鱼,我也是醉了。

反正上面这俩图我都越想越不满意,总体上还是因为轮廓的原因吧。

然后我就像自己再找一些蜘蛛轮廓,准备再做一个。

怎么做呢?

如果找到好看的轮廓,其实就是生成一个词云图就好了。

我找啊找,又搜到了几个不错的轮廓,接下来就是把这个轮廓生成词云图了。

大家可能会想,这个词云图生成也太麻烦了吧,有对应的关键字,还要符合对应的轮廓,还要同时好看,这搞起来有点难啊,目前市面上我问了下找设计师搞个词云图也得 500 块钱呢。

当然,其实 Python 也有对应的词云图生成库,但功能我觉得还是没有那么精细化。

难道要自己画?

其实不用这么麻烦,我找到了一个网站,叫做微词云,这个还是比较简单好用的,我们只需要输入关键词和每个词的频率,还能自定义想要的轮廓,它就能自动生成词云图了,如图所示:

这就是确定的一个新轮廓,这个蜘蛛是不是看起来就舒服多了?看起来既不吓人,又没那么奇怪。

最后我找了好多小伙伴也看了看最终的效果,大家都觉得这个放在封面上挺不错的。

嗯!最后就是它了!经过几天的修改,最后的效果如下:

同时在第一版封面上还加上了 Python 之父推荐的相关字样,另外「第 2 版」三个字就直接标识到了图书标题的下面。

最后的完整全封如下:

背面是四位专家的推荐语。

定价是 139.8 元,没错,这本书最后 900 多页,139.8 元,其实这个价格在这个页码基础上已经算很合算了。

书现在是什么状态呢?

现在稿子已经送到印检部啦,印前检查没问题就直接印刷啦:

等印刷出来之后我还会去印厂签上千本名,到时候就会有签名版的书搞活动送给大家哈。

请大家耐心等待几天,书很快就可以跟大家见面啦~

更多精彩内容,请关注我的公众号「进击的 Coder」和「崔庆才丨静觅」。

Python

别急,这书现在还没上市哈,但很快了。

最近朋友们一直在催:你的第二版爬虫书怎么还不出来啊,我都等了好几年了!你不是前几个月就完稿了吗?咋这么慢。

别急,这下是真的很快就要上市了。

为啥我的第二版书“难产”了呢?原因有好多:

  • 一个就是工作原因,之前第一版书是读研期间写的,工作之后发现书中的一些案例已经过期了,于是就决定写第二版。但工作毕竟是工作,工作的内容还是需要放在第一位的,所以第二版书的内容基本都是利用下班之后或者周末的时间写出来的,所以进度很慢。

  • 另外一个就是为了解决案例过期的问题,之前耗费了很多精力自己制作了爬虫案例平台,https://scrape.center/,里面做了几十个爬虫案例,书中对这些案例进行了配合讲解,这就解决了一些案例过期的问题,也能更好地帮助读者进行练习,前前后后这个案例平台做了也有小半年的时间。

等书籍完稿之后,其实还有不少的事情,比如审稿、修改、封面设计、推荐语等等,总之步骤是很繁琐的,改天再写个文章专门介绍下写书这件事。

单独说说推荐语。

推荐语就是印在书的背面的各位专家对本书的评价和推荐内容,一般就是几句话加上专家的 Title。就在推荐语这一块上,我还憋了个“大招”,那就是让 Python 之父 Guido van Rossum 给我写个推荐语。

Python 之父想必大家应该知道是谁吧?就是 Guido van Rossum,Python 就是他在 1989 年编写出来的。

有人说,你还真敢想,还想让 Python 之父给你这本“名不见经传”的书写推荐语?闹呢?人家怎么可能会理你?

其实想想确实不可思议的,但我还是想试试,如果真的能拿到 Python 之父的推荐,那简直是荣幸之至!

另外由于我在微软工作,Python 之父 Guido 2020 年也宣布加入微软。所以,我和他也多少是同一个公司的了(但显然职位差距过大)。

所以,没准还是有机会的呢?

好,那么问题来了,我这书都是中文写的,Python 之父是看不懂中文的,咋办呢?难道我要把全书都翻译一遍吗?

是的,还真得是这样,我不能给个中文内容或者啥也不给就干巴巴地要求他帮我写推荐语吧?这也太滑稽了。

在此之前,有好几个月时间整本书的内容还在审稿和修改,等稿子审完的时候差不多就九月份了,然后九月份左右,我就拿到了编辑那边给到的全书审核完毕的 Word 文档,但还没正式排版。看了看,这个 Word 文档一共有 1000 多页,好家伙,我真的不敢相信我写了这么多。

但也没办法,那也得翻译一遍。

如果我全部手工翻译也太麻烦了,于是我就从网上找了一些工具,比如 Word 全文翻译工具,其背后就是对接了 Google 翻译,但这些工具还有上传大小限制,于是我就又把各个章节进行了拆分,一部分一部分地翻译完了再合并起来。

当然大家知道,Google 翻译肯定质量不能保证的吧,比如一些说法和名词就翻译不太准确,我就得进行手工审查和修改。所以我又花了好多天时间对全文进行检查和修改,包括不准确的标题、表述、名词等等。然后我还对整个目录索引重新规整了一遍。

总之整个翻译准备过程差不多也花了半个月的时间,最后翻译完了英文版差不多 1600 页,如图所示,比如目录最后一节就是 1561 页了:

全书翻译

但是,这个其实还不够,如果把这个书丢过去,人家没时间看怎么办?我总得好好介绍下整本书的情况吧。

于是我又把书的介绍和前言又翻译了一遍,内容包括:写书的初衷、整本书的介绍、整体章节的规划,这样的话能帮助 Guido 更好地理解整本书的脉络和内容。

于是又有了如下的内容:

书的介绍

好像还是不够,万一 Guido 觉得写推荐语很麻烦怎么办?如果我能给他提供几个 Draft Candidate 候选是不是更有帮助一些?这样他可以找些灵感或者稍微修改下就好了,于是我又草拟了一些候选推荐语,整理了一个文档。

嗯,好像就准备差不多了,一共三个东西:

  • 全书的翻译内容

  • 书的内容介绍

  • 候选推荐语

接下来就是联系 Guido 了,心中一阵忐忑。

为了更正式一点,我发了一封邮件给 Guido,邮件整体的内容就是:先表示下对他的感谢和敬佩,然后介绍下自己的基本情况和书的基本情况,比如我是做什么的,第一版书在中国的销量等等,接着开门见山地说想要请他帮忙写一段推荐语。然后后面就附上我的书的一些详细信息,比如我整理的全文翻译书稿、内容介绍、候选推荐语等。

内容如下:

我怀着十分忐忑而又激动的心情,按下了发送键。

接下来就是漫长的等待。

我每天早上醒来都会看看邮件有没有收到 Guido 的回信。

没回。

还是没回。

还是还是没回。

还是还是还是没回。

好像要凉了。

好像凉了。

好像真凉了。

真的凉了。

可能真的是太忙或者没看到我的邮件吧。

后来,我就联系了我们部门的总 Director(这里就不透露具体信息了),看看他能不能帮我 connect 一下 Guido,他爽快地答应了。

不太清楚我的 Director 怎么联系的,他说单独找了下 Guido,可能是发信或者内部联系。

然后第二天,他就告诉我,得到 Guido 回复了!Guido 说确实近期比较忙,也很希望能有一个 Draft Candidate 推荐语提供给他,他可以结合着书的内容来改写一下会更好。

我的 Director 人也非常好,他也给我出了很多建议,还帮我修改了下之前我写的 Draft Candidate 推荐语给他,转发了我的邮件还帮我又介绍了下。

最后,Guido 给了最终的推荐语!!

Guido 的回信,遮盖了部分邮件内容

收到这封邮件的时候我真的开心地要跳起来了,太开心了!我的书得终于拿到了 Python 之父的推荐啦!

正文如下:

I am happy to see that Python is so widely used in the Chinese IT community. I hope this book will help more people understand Python and web crawling/scraping. *

—Guido van Rossum, creator of Python, Distinguished Engineer, Microsoft

大意就是,我非常高兴 Python 能够在中国社区得到这么广泛的应用,希望本书能够帮助更多的朋友学习 Python 和网络爬虫。

嗯,整个过程比较漫长,但真的非常开心最终有了一个好的结果,真的非常荣幸能获得 Python 之父的推荐,同时也非常感谢我的 Director 帮我联系和出建议。

得到 Guido 的推荐语之后,后面的流程就很快了,还有其他各位专家的推荐语和序我也都联系好了,真的非常感谢各位专家的推荐,书中都会一一表示感谢。

现在内容也审核完毕了,最后把推荐语添加到封面上就投入印刷了!

请大家再耐心等待一小段时间,很快《Python3 网络爬虫开发实战(第二版)》就要跟大家见面啦~

更多精彩内容,请关注我的公众号「进击的 Coder」和「崔庆才丨静觅」。

个人随笔

大家有没有这样的一个经历:

周末和节假日出去疯玩了几天,期间没有任何学习或总结,到了周一前或者到了晚上的时候,会不会感觉到有点焦虑?比如就会想:我怎么今天又玩了一天,我还有什么什么事还没做呢,还有什么什么东西还没学呢,今天都没有什么进步,诸如此类的吧,然后就产生了一种焦虑感,想去做点什么事情找补一下。

我也有这样的情况。

我觉得我可能是一个自我 Push 比较强的人。比如有一天,我觉得自己做的东西没什么意义,或者疯玩了一天也没有学习和进步,到了一天结束的时候就会感到有些焦虑。我就想通过一些事情找补点什么回来,于是可能就想熬夜看点或者学习点东西。但实际上,有时候我也不知道应该看点什么,但总觉得需要学点或者看点什么,以“欺骗”自己的大脑今天我学习了,进步了,然后焦虑就会缓解一些。当然也有时候确实也知道自己每天还有什么事情没有完成,做完了焦虑就缓解了。

但长期以来,我感觉这样其实是不健康的,我也一直在思考我应该做点什么来解决这个问题。

经历了一些思考和尝试之后,我发现了其中的一个原因:当我给自己没有制定明确的计划和目标的时候,这种焦虑就会很频繁发生。

这个计划和目标分为长期的和短期的,长期目标和规划比较大、比较远或者说比较空洞,而短期目标和规划就是为了长期目标而制定的具体的执行方案,更能使我们焦虑的,就是短期目标和规划的缺失。

假如我没有为自己制定短期的计划,到了周末不上班的时候,就会突然不知道自己应该做些什么,至少在那一天我不知道应该做些什么。由于没有当天的规划,所以那天可能就漫无目的地休闲娱乐,比如说赖床、躺尸、刷手机(比如微博、知乎、朋友圈、抖音等)、玩游戏等等,当然也有时候无聊了就约朋友出去玩,但时间就这么一点点过去了。等到晚上到来,我就会发现,这一天怎么这么快就过去了?我好像今天也没有干什么事情,我就会焦虑,觉得今天也没有做有意义的事情,觉得我拥有的能够达成我的长期目标的时间和机会又变少了。因为长期计划会隐藏在我的潜意识里,我想达成某个大的目标,但经历了无所事事的一天之后,就会觉得我又浪费了一天,就会感觉到我能达成长期目标的几率仿佛又变小了,焦虑感就油然而生了。

为了验证我的这个想法,我就有意识地进行一些测试,比如在某一段时间我就不给自己制定短期和具体计划,任凭想到啥做啥,然后就发现那个时间段焦虑感很强。然后我就又尝试梳理自己的一些目标和具体每天应该做的一些事情,每天按照我的计划去执行,每天完成了既定计划之后,就会感觉很踏实。甚至完成了既定计划之后还能超额再做点什么的时候,就会感觉成就感爆棚。

嗯,总之,经过我的一些尝试之后,就感觉 —— 为自己制定短期的目标和规划真的很有帮助,这个短期的目标和规划时间段可能在一个月或者几周,先想这个月或者几周应该去做些什么,然后细化到每天应该去做些什么,这个一定要列详细,不要空洞,然后最好还能标记好优先级。就比如说,我规划一个月可能要学一门课程,那么我就分配一下,我哪一天需要具体学从第几节到第几节的内容,记录到我的 Todo List 里面。我是用的「滴答清单」这款软件,在里面我就给我每天需要做的事情做好分配,这样每天我就知道自己需要做什么了。

但这时候有朋友可能就说,难道你周末规划的也全是学习和工作吗?娱乐、放松呢?这个当然也是有的。我觉得人不能把自己逼的太紧了,每天都紧绷着做各种各样的事情,弦会断的。所以,有时候我就会给自己规划有些时间段就是可以放松和玩的,比如周五晚上就玩游戏、周六上午就赖床多睡会、周末也会规划时间出去玩等等。

所以,做好了规划,不论是学习、工作还是放松、娱乐,这都是在自己的期望和规划之中。比如我就规划了某个时间段去放空自己玩两天,那两天就全身心放松玩两天,那也不会有什么焦虑,因为这就在我的期望之内,我知道玩完这两天,我后面的一些规划时间和事情仍然可以正常完成我做达成的短期和长期目标,焦虑感自然就不会产生了。

嗯,就是这样。如果你也遇到了文章一开始我提到的问题,不妨尝试给自己制定一个详细的短期目标和规划吧。

更多精彩内容,请关注我的公众号「进击的 Coder」和「崔庆才丨静觅」。

安装配置

Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。

如果你还不了解 YML 文件配置,可以先阅读 YAML 入门教程

Compose 使用的三个步骤:

  • 使用 Dockerfile 定义应用程序的环境。
  • 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
  • 最后,执行 docker-compose up 命令来启动并运行整个应用程序。

安装

当前,最新的 Docker 已经把 Compose 作为 Docker 的命令一部分了,可以直接安装 Docker:https://setup.scrape.center/docker

另外如果要单独安装 Docker-Compose,可以参考 https://www.runoob.com/docker/docker-compose.html

安装配置

Helm 是 Kubernetes 的包管理器。

相关链接

该指南展示了如何安装 Helm CLI。Helm 可以用源码或构建的二进制版本安装。

下面的内容来自:https://helm.sh/zh/docs/intro/install/,最新内容以该链接为准。

用 Helm 项目安装

Helm 项目提供了两种获取和安装 Helm 的方式。这是官方提供的获取 Helm 发布版本的方法。另外, Helm 社区提供了通过不同包管理器安装 Helm 的方法。这些方法可以在下面的官方方法之后看到。

用二进制版本安装

每个 Helm 版本都提供了各种操作系统的二进制版本,这些版本可以手动下载和安装。

  1. 下载 需要的版本
  2. 解压(tar -zxvf helm-v3.0.0-linux-amd64.tar.gz)
  3. 在解压目中找到helm程序,移动到需要的目录中(mv linux-amd64/helm /usr/local/bin/helm)

然后就可以执行客户端程序并 添加稳定仓库: helm help.

注意 针对 Linux AMD64,Helm 的自动测试只有在 CircleCi 构建和发布时才会执行。测试其他操作系统是社区针对系统问题请求 Helm 的责任。

使用脚本安装

Helm 现在有个安装脚本可以自动拉取最新的 Helm 版本并在 本地安装

您可以获取这个脚本并在本地执行。它良好的文档会让您在执行之前知道脚本都做了什么。

1
2
3
$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
$ chmod 700 get_helm.sh
$ ./get_helm.sh

如果想直接执行安装,运行curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

通过包管理器安装

Helm 社区提供了通过操作系统包管理器安装 Helm 的方式。但 Helm 项目不支持且不认为是可信的第三方。

使用 Homebrew (macOS)

Helm 社区成员贡献了一种在 Homebrew 构建 Helm 的方案,这个方案通常是最新的。

1
brew install helm

(注意:还有一个 emacs-helm 的方案,当然这是另一个项目了。)

使用 Chocolatey (Windows)

Helm 社区成员贡献了一个 Helm 包Chocolatey中构建, 包通常是最新的。

1
choco install kubernetes-helm

使用 Apt (Debian/Ubuntu)

Helm 社区成员贡献了针对 Apt 的一个 Helm 包,包通常是最新的。

1
2
3
4
5
curl https://baltocdn.com/helm/signing.asc | sudo apt-key add -
sudo apt-get install apt-transport-https --yes
echo "deb https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helm

使用 Snap

Snapcrafters社区维护了 Helm 包的 Snap 版本:

1
sudo snap install helm --classic

使用 pkg (FreeBSD)

FreeBSD 社区成员贡献了一个 Helm 页面来构建 FreeBSD 端口集。通常都是最新的包。

1
pkg install helm

开发版本构建

另外您可以下载和安装 Helm 的开发版本。

使用 Canary 构建

“Canary”版本是从 Helm 最新的 master 分支构建。这些不是官方版本,可能不稳定。但是这提供测试边缘特性的条件。

Canary Helm 二进制包存储在 get.helm.sh。以下是一般构建的链接:

使用源码 Source (Linux, macOS)

从源码构建 Helm 的工作要稍微多一点,但如果你想测试最新(预发布)的 Helm 版本,这是最好的方式。

您必须有可用的 Go 环境。

1
2
3
$ git clone https://github.com/helm/helm.git
$ cd helm
$ make

如果需要,会拉取依赖并缓存,然后验证配置。然后会编译helm并放在bin/helm

总结

大多数情况下,安装只需要简单地获取一个构建好的helm二进制包。本文档为想使用 Helm 做更复杂事情的人提供额外示例。

一旦你成功安装了 Helm 客户端,就可以继续使用 Helm 管理 chart 和 添加稳定的仓库

安装配置

Kubernetes,又被简称作 K8s(K 和 s 中间含有 8 个字母),它是用于编排容器化应用程序的云原生系统。Kubernetes 诞生自 Google,现在已经由 CNCF (云原生计算基金会)维护更新。Kubernetes 是目前最受欢迎的集群管理方案之一,可以非常容易地实现容器的管理编排。

刚刚我们提到,Kubernetes 是一个容器编排系统,对于“编排”二字,可能不太容易理解其中的含义。为了对它有更好的理解,我们先回过头来看看容器的定位是什么以及容器解决了什么问题,不能解决什么问题,然后我们再来了解下 Kubernetes 能够弥补容器哪些缺失的内容。

好,首先来看容器。最常见的容器技术就是 Docker 了,容器它提供了相比传统虚拟化技术更轻量级的机制来创建隔离的应用程序的运行环境。比如对于某个应用程序,我们使用容器运行时,不必担心它与宿主机之间产生资源冲突,不必担心多个容器之间产生资源冲突。同时借助于容器技术,我们还能更好地保证开发环境和生产环境的运行一致性。另外由于每个容器都是独立的,因此可以将多个容器运行在同一台宿主机上,以提高宿主机资源利用率,从而也进一步降低了成本。总之,使用容器带来的好处很多,可以为我们带来极大的便利。

不过单单依靠容器技术并不能解决所有的问题,也可以说容器技术也引入了新的问题,比如说:

  • 如果容器突然运行异常了怎么办?
  • 如果容器所在的宿主机突然运行异常了怎么办?
  • 如果有多个容器,他们之间怎么有效地传输数据?
  • 如果单个容器达到了瓶颈,如何平稳且有效地进行扩容?
  • 如果生产环境是由多台主机组成的,我们怎样更好地决定使用哪台主机来运行哪个容器?

以上列举了一些单纯依靠容器技术或者单纯依靠 Docker 不能解决的问题,而 Kubernetes 作为容器编排平台,提供了一个可弹性运行的分布式系统框架,各个容器可以运行在 Kubernetes 平台上,容器的管理、调度、部署、扩容等各个操作都可以经由 Kubernetes 来有效实现。比如说,Kubernetes 可以管理单个容器的声明周期,并且可以根据需要来扩展和释放资源,如果某个容器意外关闭,Kubernetes 可以根据对应的策略选择重启该容器,以保证服务的正常运行。再比如说,Kubernetes 是一个分布式的平台,当容器所在的主机突然发生异常,Kubernetes 可以将异常主机上运行的容器转移到其他正常的主机上运行,另外 Kubernetes 还可以根据容器运行所需要占用的资源自动选择合适的主机来运行。总之,Kubernetes 对容器的调度和管理提供了非常强大的支持,可以帮我们解决上述的诸多问题。

相关资料

安装方式

安装 Kubernetes 有好多方式,比如 Minicube、Docker 自带、自建集群、云服务商提供。

Minicube

参考:https://kubernetes.io/docs/tutorials/hello-minikube/

Docker 自带

现在 Docker for Windows 和 Docker for Mac 已经自带了 Kubernetes 的集群功能,只需要打开对应开关即可,如图所示:

image-20211004003229922

这里只需要把 Enable Kubernetes 勾选即可。

集群搭建

搭建 Kubernetes 集群是比较麻烦的,参考链接:

云服务商

很多云服务商已经提供了 Kubernetes,请移步对应云服务商的功能支持说明,参考链接:

安装配置

用 Splash 做页面抓取时,如果爬取的量非常大,任务非常多,用一个 Splash 服务来处理的话,未免压力太大了,此时可以考虑搭建一个负载均衡器来把压力分散到各个服务器上。这相当于多台机器多个服务共同参与任务的处理,可以减小单个 Splash 服务的压力。

配置 Splash 服务

要搭建 Splash 负载均衡,首先要有多个 Splash 服务。假如这里在 4 台远程主机的 8050 端口上都开启了 Splash 服务,它们的服务地址分别为 41.159.27.223:8050、41.159.27.221:8050、41.159.27.9:8050 和 41.159.117.119:8050,这 4 个服务完全一致,都是通过 Docker 的 Splash 镜像开启的。访问其中任何一个服务时,都可以使用 Splash 服务。

具体的 Splash 搭建流程可以参考:https://setup.scrape.center/splash

配置负载均衡

接下来,可以选用任意一台带有公网 IP 的主机来配置负载均衡。首先,在这台主机上装好 Nginx,然后修改 Nginx 的配置文件 nginx.conf,添加如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
http {
upstream splash {
least_conn;
server 41.159.27.223:8050;
server 41.159.27.221:8050;
server 41.159.27.9:8050;
server 41.159.117.119:8050;
}
server {
listen 8050;
location / {proxy_pass http://splash;}
}
}

这样我们通过 upstream 字段定义了一个名字叫作 splash 的服务集群配置。其中 least_conn 代表最少链接负载均衡,它适合处理请求处理时间长短不一造成服务器过载的情况。

当然,我们也可以不指定配置,具体如下:

1
2
3
4
5
6
upstream splash {
server 41.159.27.223:8050;
server 41.159.27.221:8050;
server 41.159.27.9:8050;
server 41.159.117.119:8050;
}

这样默认以轮询策略实现负载均衡,每个服务器的压力相同。此策略适合服务器配置相当、无状态且短平快的服务使用。

另外,我们还可以指定权重,配置如下:

1
2
3
4
5
6
upstream splash {
server 41.159.27.223:8050 weight=4;
server 41.159.27.221:8050 weight=2;
server 41.159.27.9:8050 weight=2;
server 41.159.117.119:8050 weight=1;
}

这里 weight 参数指定各个服务的权重,权重越高,分配到处理的请求越多。假如不同的服务器配置差别比较大的话,可以使用此种配置。

最后,还有一种 IP 散列负载均衡,配置如下:

1
2
3
4
5
6
7
upstream splash {
ip_hash;
server 41.159.27.223:8050;
server 41.159.27.221:8050;
server 41.159.27.9:8050;
server 41.159.117.119:8050;
}

服务器根据请求客户端的 IP 地址进行散列计算,确保使用同一个服务器响应请求,这种策略适合有状态的服务,比如用户登录后访问某个页面的情形。对于 Splash 来说,不需要应用此设置。

我们可以根据不同的情形选用不同的配置,配置完成后重启一下 Nginx 服务:

1
sudo nginx -s reload

这样直接访问 Nginx 所在服务器的 8050 端口,即可实现负载均衡了。

配置认证

现在 Splash 是可以公开访问的,如果不想让其公开访问,还可以配置认证,这仍然借助于 Nginx。可以在 serverlocation 字段中添加 auth_basicauth_basic_user_file 字段,具体配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
http {
upstream splash {
least_conn;
server 41.159.27.223:8050;
server 41.159.27.221:8050;
server 41.159.27.9:8050;
server 41.159.117.119:8050;
}
server {
listen 8050;
location / {
proxy_pass http://splash;
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
}
}
}

这里使用的用户名和密码配置放置在 /etc/nginx/conf.d 目录下,我们需要使用 htpasswd 命令创建。例如,创建一个用户名为 admin 的文件,相关命令如下:

1
htpasswd -c .htpasswd admin

接下来,就会提示我们输入密码。输入两次之后,就会生成密码文件,其内容如下:

1
2
cat .htpasswd
admin:5ZBxQr0rCqwbc

配置完成后重启一下 Nginx 服务,运行如下命令:

1
sudo nginx -s reload

这样访问认证就成功配置好了。

测试

最后,我们可以用代码来测试一下负载均衡的配置,看看到底是不是每次请求会切换 IP。利用 http://httpbin.org/get 测试即可,实现代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import requests
from urllib.parse import quote
import re

lua = '''
function main(splash, args)
local treat = require("treat")
local response = splash:http_get("http://httpbin.org/get")
return treat.as_string(response.body)
end
'''

url = 'http://splash:8050/execute?lua_source=' + quote(lua)
response = requests.get(url, auth=('admin', 'admin'))
ip = re.search('(\d+\.\d+\.\d+\.\d+)', response.text).group(1)
print(ip)

这里 URL 中的 splash 字符串请自行替换成自己的 Nginx 服务器 IP。这里我修改了 Hosts,设置了 splash 为 Nginx 服务器 IP。

多次运行代码之后,可以发现每次请求的 IP 都会变化,比如第一次的结果:

1
41.159.27.223

第二次的结果:

1
41.159.27.9

这就说明负载均衡已经成功实现了,配置负载均衡后,可以多个 Splash 服务共同合作,减轻单个服务的负载,这还是比较有用的。

当然,我们也可以借助于 Kubernetes + Docker 来实现负载均衡,管理起来更加简单方便,感兴趣可以搜索相关内容试验一下。

安装配置

爬虫过程中难免会遇到各种各样的验证码,而大多数验证码还是图形验证码,这时候我们可以直接用 OCR 来识别。

OCR

OCR,即 Optical Character Recognition,光学字符识别。是指通过扫描字符,然后通过其形状将其翻译成电子文本的过程。那么对于图形验证码来说,它都是一些不规则的字符,但是这些字符确实是由字符稍加扭曲变换得到的内容。

例如这样的验证码,如图所示:

对于这种验证码,我们便可以使用 OCR 技术来将其转化为电子文本,然后爬虫将识别结果提交给服务器,便可以达到自动识别验证码的过程。

Tesserocr 是 Python 的一个 OCR 识别库,但其实是对 Tesseract 做的一层 Python API 封装,所以它的核心是 Tesseract,所以在安装 Tesserocr 之前我们需要先安装 Tesseract,本节我们来了解下它们的安装方式。

相关链接

Windows 下的安装

本小节内容来自于:https://segmentfault.com/a/1190000039929696,可以移步此链接查看原文。

另外也可以查看其他博文,如:https://cloud.tencent.com/developer/article/1616037 来安装和排查。

为了增大成功安装的几率,推荐使用 Python 3.7 版本。

在 Windows 下,首先需要下载 Tesseract,它为 Tesserocr 提供了支持,下载链接为:http://digi.bib.uni-mannheim.de/tesseract/

点击进入之后可以看到有各种 exe 的下载列表,在这里可以选择下载 4.0 版本 tesseract-ocr-setup-4.00.00dev.exe,如图所示:

其中文件名中带有 dev 的为开发版本,不带 dev 的为稳定版本。

下载完成之后双击安装即可,在安装过程中可以勾选上 Additional language data 选项,安装 OCR 识别支持的语言包,这样 OCR 便可以识别多国语言。

复制你的安装路径,我的安装路径 D:\Python\Tesseract-OCR,界面如下:

打开我的电脑系统属性->高级->环境变量,把该路径配置到环境变量:

然后将下载好的字库放到 Tesseract-OCR 项目的 tessdata 文件夹里面。

接下来再安装 Tesserocr 即可,直接使用 Pip 安装:

1
pip3 install tesserocr pillow

另外如果安装过程中出现错误,请移步官方安装说明排查问题:https://github.com/sirfz/tesserocr

Linux 下的安装

对于 Linux 来说,不同系统已经有了不同的发行包了,它可能叫做 tesseract-ocr 或者 tesseract,直接用对应的命令安装即可。

Ubuntu、Debian、Deepin

安装命令如下:

1
sudo apt-get install -y tesseract-ocr libtesseract-dev libleptonica-dev

CentOS、RedHat

安装命令如下:

1
yum install -y tesseract

不同发行版本运行如上命令即可完成 Tesseract 的安装。

安装完成之后便可以调用 tesseract 命令了。

我们查看一下其支持的语言:

1
tesseract --list-langs

运行结果示例:

1
2
3
4
List of available languages (3):
eng
osd
equ

结果显示其只支持几种语言,如果我们想要安装多国语言还需要安装语言包,官方叫做 tessdata。

tessdata 的下载链接为:https://github.com/tesseract-ocr/tessdata

利用 Git 命令将其下载下来并迁移到相关目录即可,不同的版本迁移命令如下:

Ubuntu、Debian、Deepin

1
2
git clone https://github.com/tesseract-ocr/tessdata.git
sudo mv tessdata/* /usr/share/tesseract-ocr/tessdata

CentOS、RedHat

1
2
git clone https://github.com/tesseract-ocr/tessdata.git
sudo mv tessdata/* /usr/share/tesseract/tessdata

这样就可以将下载下来的语言包全部安装了。

这时我们重新运行列出所有语言的命令:

1
tesseract --list-langs

结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
List of available languages (107):
afr
amh
ara
asm
aze
aze_cyrl
bel
ben
bod
bos
bul
cat
ceb
ces
chi_sim
chi_tra
...

即可发现其列出的语言就多了非常多,比如 chi_sim 就代表简体中文,这就证明语言包安装成功了。

接下来再安装 Tesserocr 即可,直接使用 Pip 安装:

1
pip3 install tesserocr pillow

Mac 下的安装

Mac 下首先使用 Homebrew 安装 Imagemagick 和 Tesseract 库:

1
2
brew install imagemagick
brew install tesseract --all-languages

接下来再安装 Tesserocr 即可:

1
pip3 install tesserocr pillow

这样我们便完成了 Tesserocr 的安装。

验证安装

接下来我们可以使用 Tesseract 和 Tesserocr 来分别进行测试。

下面我们以如下的图片为样例进行测试,如图所示:

图片链接为:https://raw.githubusercontent.com/Python3WebSpider/TestTess/master/image.png,可以直接保存或下载。

我们首先用命令行进行测试,将图片下载保存为 image.png,然后用 Tesseract 命令行测试,命令如下:

1
tesseract image.png result -l eng && cat result.txt

运行结果:

1
2
Tesseract Open Source OCR Engine v3.05.01 with Leptonica
Python3WebSpider

我们调用了 tesseract 命令,第一个参数为图片名称,第二个参数 result 为结果保存的目标文件名称,-l 指定使用的语言包,在此使用 eng 英文,然后再用 cat 命令将结果输出。

第二行的运行结果便是图片的识别结果,Python3WebSpider。

我们可以看到这时已经成功将图片文字转为电子文本了。

然后我们还可以利用 Python 代码来测试,这里就需要借助于 Tesserocr 库了,测试代码如下:

1
2
3
4
import tesserocr
from PIL import Image
image = Image.open('image.png')
print(tesserocr.image_to_text(image))

在这里我们首先利用 Image 读取了图片文件,然后调用了 tesserocr 的 image_to_text() 方法,再将将其识别结果输出。

运行结果:

1
Python3WebSpider

另外我们还可以直接调用 file_to_text() 方法,也可以达到同样的效果:

1
2
import tesserocr
print(tesserocr.file_to_text('image.png'))

运行结果:

1
Python3WebSpider

如果成功输出结果,则证明 Tesseract 和 Tesserocr 都已经安装成功。

安装配置

Frida 是一个基于 Python 和 JavaScript 的 Hook 与调试框架,是一款易用的跨平台 Hook 工具,无 论 Java 层的逻辑,还是 Native 层的逻辑,它都可以 Hook。Frida 可以把代码插入原生 App 的内存空 间,然后动态地监视和修改其行为,支持 Windows、Mac、Linux、Android、iOS 全平台。

相关链接

安装

pip 安装

推荐使用 pip3 安装,命令如下:

1
pip3 install frida frida-tools

命令执行完毕之后即可完成安装。

验证安装

安装完成之后,可以在 Python 命令行下测试。

1
2
$ python3
>>> import frida

如果没有错误报出,则证明库已经安装好了。

更多安装说明参考:https://frida.re/docs/installation/

安装配置

IDA Pro 的英文全称是 Interactive Disassembler Professional,即交互式反汇编器专业版,大家也称 之为 IDA。它由一家总部位于比利时的 Hex-Rayd 公司开发,功能十分强大,是目前流行的反汇编软 件之一,也是安全分析人士必备的一款软件。

IDA Pro 最重要的功能便是可以将二进制文件中的机器代码(如 010101)转化成汇编代码,甚至 可以进一步根据汇编代码的执行逻辑还原出高级语言(如 C/C++)编写的代码,从而大大提高代码的 可读性。IDA Pro 不仅仅局限于分析 Android 中的 so 文件,它可以处理和分析几乎所有的二进制文件, Windows、DOS、Unix、Linux、Mac、Java、.NET 等平台的二进制文件都不在话下。另外,IDA Pro 提 供了图形界面和强大的调试功能,利用它我们可以直观地实时调试和分析二进制文件。除了这些,IDA Pro 还提供开放式的插件架构,我们可以编写自定义的插件轻松扩展其功能。

总之,IDA Pro 是一款极其强大的反汇编软件,已经成为业界安全分析必不可少的一个工具,更多介绍可以查看 IDA Pro 的官网。

安装

IDA Pro 是收费的,但是有不少大佬已经破解了,可以移步相关资源查看:https://bbs.pediy.com/thread-263559.htm

其他的安装教程:

安装配置

VirtualXposed 是基于VirtualAppepic非 ROOT环境下运行 Xposed 模块的实现(支持 5.0~10.0)。

与 Xposed 相比,目前 VirtualXposed 有两个限制:

  1. 不支持修改系统(可以修改普通 APP 中对系统 API 的调用),因此重力工具箱,应用控制器等无法使用。
  2. 暂不支持资源 HOOK,因此资源钩子不会起任何作用;使用资源 HOOK 的模块,相应的功能不会生效。

相关链接

安装

可以到 https://github.com/android-hacker/VirtualXposed/releases 下载最新的安装包,如图所示:

image-20211004001344424

下载下来 apk 之后直接安装即可:

1
adb install VirtualXposed_0.20.3.apk

使用说明见:https://vxposed.com/,中文文档见:https://github.com/android-hacker/VirtualXposed/blob/vxp/CHINESE.md

安装配置

PyExecJS 是一个可以模拟调用 JavaScript 脚本的 Python 库。

相关链接

准备工作

PyExecJS 需要 Node.js 执行环境,请先安装 Node.js,参考:https://setup.scrape.center/nodejs。

安装方法

pip 安装

推荐使用 pip3 安装,命令如下:

1
pip3 install PyExecJS

命令执行完毕之后即可完成安装。

验证安装

安装完成之后,可以在 Python 命令行下测试。

1
2
$ python3
>>> import execjs

如果没有错误报出,则证明库已经安装好了。

安装配置

Elasticsearch 也有对应的 Python 库,名称也叫 Elasticsearch。

相关链接

准备工作

Elasticsearch 的 Python 库需要和 Elasticsearch 配合使用,在此之前请安装 Elasticsearch,安装教程参考: https://setup.scrape.center/elasticsearch。

安装方法

pip 安装

推荐使用 pip3 安装,命令如下:

1
pip3 install elasticsearch

命令执行完毕之后即可完成安装。

如果要支持异步 async,可以安装如下包:

1
pip3 install elasticsearch[async]

验证安装

安装完成之后,可以在 Python 命令行下测试。

1
2
$ python3
>>> import elasticsearch

如果没有错误报出,则证明库已经安装好了。

安装配置

Motor 是 PyMongo 的支持异步的库。

相关链接

安装

pip 安装

推荐使用 pip3 安装,命令如下:

1
pip3 install motor

命令执行完毕之后即可完成安装。

验证安装

安装完成之后,可以在 Python 命令行下测试。

1
2
$ python3
>>> import motor

如果没有错误报出,则证明库已经安装好了。

安装配置

Numpy 是 Python 中的一个科学计算库,功能非常强大。

相关链接

安装方法

pip 安装

推荐使用 pip3 安装,命令如下:

1
pip3 install numpy

命令执行完毕之后即可完成安装。

验证安装

安装完成之后,可以在 Python 命令行下测试。

1
2
$ python3
>>> import numpy

如果没有错误报出,则证明库已经安装好了。

安装配置

Pyppeteer 是一个自动化测试框架,是 Puppteer 的 Python 版本。

相关链接

安装

pip 安装

推荐使用 pip3 安装,命令如下:

1
pip3 install pyppeteer

命令执行完毕之后即可完成安装。

安装完成之后可以运行如下命令进行一些初始化操作:

1
pyppeteer-install

运行之后 Pyppeteer 会下载一个 Chromium 浏览器并配置好环境变量。

验证安装

安装完成之后,可以在 Python 命令行下测试。

1
2
$ python3
>>> import pyppeteer

如果没有错误报出,则证明库已经安装好了。

另外还可以运行测试脚本:

1
2
3
4
5
6
7
8
9
10
11
import asyncio
from pyppeteer import launch

async def main():
browser = await launch()
page = await browser.newPage()
await page.goto('https://www.baidu.com')
await page.screenshot({'path': 'baidu.png'})
await browser.close()

asyncio.get_event_loop().run_until_complete(main())

运行之后,如果之前没有运行过 pyppeteer-install 命令的话,Pyppeteer 会进行一些初始化配置,运行完毕之后,就会启动浏览器,然后访问百度,生成截图。

安装配置

Redis 是一个基于内存的高效的非关系型数据库,本节我们来了解下 Redis 在各个平台的安装过程。

相关链接

Windows 下的安装

Redis 在 Windows 下可以直接到 https://redis.io/downloadhttps://nowjava.com/download/31283 下载。

安装过程比较简单,直接点击下一步安装即可,安装完成之后 Redis 便会启动。

在系统服务里可以观察到多了一个正在运行到 Redis 服务,如图所示:

img

另外推荐下载一个 Redis Desktop Manager 可视化管理工具,来管理 Redis。

可以到官方网站下载,链接为:https://redisdesktop.com/download 也可以到 GitHub 下载最新发行版本,链接为:https://github.com/uglide/RedisDesktopManager/releases

安装之后直接连接本地 Redis 即可,简单方便。

Linux 下的安装

这里依然还是分为两类平台介绍。

Ubuntu、Debian、Deepin

使用 apt-get 命令行安装:

1
sudo apt-get -y install redis-server

运行如上命令即可完成 Redis 的安装,然后输入 redis-cli 即可进入 Redis 命令行模式。

1
2
3
4
5
$ redis-cli
127.0.0.1:6379> set 'name' 'Germey'
OK
127.0.0.1:6379> get 'name'
"Germey"

这样就证明 Redis 成功安装了,但是现在 Redis 还是无法远程连接的,依然需要修改配置文件,配置文件路径为 /etc/redis/redis.conf。

注释这一行:

1
bind 127.0.0.1

另外推荐给 Redis 设置密码,取消注释这一行:

1
requirepass foobared

foobared 即当前密码,可以自行修改。

然后重启 Redis 服务,使用如下命令:

1
sudo /etc/init.d/redis-server restart

现在就可以使用密码远程连接 Redis 了。

另外停止和启动 Redis 服务的命令如下:

1
2
sudo /etc/init.d/redis-server stop
sudo /etc/init.d/redis-server start

CentOS、RedHat

首先添加 EPEL 仓库,然后更新 Yum 源:

1
2
sudo yum install epel-release
sudo yum update

然后安装 Redis 数据库:

1
sudo yum -y install redis

安装好之后启动 Redis 服务:

1
sudo systemctl start redis

同样可以使用 redis-cli 进入 Redis 命令行模式操作。

另外为了可以使 Redis 能被远程连接,需要修改配置文件,路径为 /etc/redis.conf。

注释这一行:

1
bind 127.0.0.1

另外推荐给 Redis 设置密码,取消注释这一行:

1
requirepass foobared

foobared 即当前密码,可以自行修改。

之后保存重启 Redis 服务:

1
sudo systemctl restart redis

这样就可以远程连接 Redis 了。

Mac 下的安装

推荐使用 Homenbrew 安装,执行 brew 命令即可。

1
brew install redis

启动 Redis 服务:

1
2
brew services start redis
redis-server /usr/local/etc/redis.conf

这样就启动了 Redis 服务。

同样可以使用 redis-cli 进入 Redis 命令行模式。

Mac 下 Redis 的配置文件路径是 /usr/local/etc/redis.conf,可以通过修改它来配置访问密码。

修改配置文件后需要重启 Redis 服务,停止、重启 Redis 服务的命令如下:

1
2
brew services stop redis
brew services restart redis

另外在 Mac 下也可以安装 Redis Desktop Manager 可视化管理工具来管理 Redis。

安装配置

retrying 提供了一些装饰器,使得我们非常方便地配置重试机制。

本节我们了解下 retrying 的安装方式。

相关链接

安装方法

pip 安装

推荐使用 pip3 安装,命令如下:

1
pip3 install retrying

命令执行完毕之后即可完成安装。

验证安装

安装完成之后,可以在 Python 命令行下测试。

1
2
$ python3
>>> import retrying

如果没有错误报出,则证明库已经安装好了。

安装配置

Xposed 框架是一套开源的,在 Android 高权限模式下运行的框架服务,它可以在不修改 App 源码的情况下影响程序运行(修改系统)的框架服务。基于 Xposed,可以制作出许多功能强大的模块,且在功能不冲突的情况下同时运作。

其实现原理我们稍作了解即可:Xposed 框架的原理是通过替换系统级别的 /system/bin/app_process 程序控制 zygote 进程,使得app_process 在启动过程中加载 XposedBridge.jar,这个 jar 包里面定义了对系统方法、属性的一系列 Hook 操作,同时还提供了几个 Hook API 供我们编写 Xposed 模块使用。我们在编写 Xposed 模块时,引用 Xposed 提供的几个 Hook 方法就可以实现对系统级别任意方法和属性的修改了。

安装

请移步:https://cn.sync-computers.com/how-install-xposed-framework

安装配置

ElasticSearch 是一个分布式的,高性能,高可用的,可伸缩的搜索和分析系统

(1)可以作为大型分布式集群(数百台服务器)技术,处理 PB 级的数据,服务大公司;也可以运行在单机上服务于小公司

(2)Elasticsearch 不是什么新技术,主要是将全文检索、数据分析以及分布式技术,合并在了一起,才形成了独一无二的 ES:lucene(全文检索),商用的数据分析软件,分布式数据库

(3)对用户而言,是开箱即用的,非常简单,作为中小型应用,直接 3 分钟部署一下 ES,就可以作为生产环境的系统来使用了,此时的场景是数据量不大,操作不是太复杂

(4)数据库的功能面对很多领域是不够用的(事务,还有各种联机事务型的操作);

特殊的功能,比如全文检索,同义词处理,相关度排名,复杂数据分析,海量数据的近实时处理,Elasticsearch 作为传统数据库的一个补充,提供了数据库所不能提供的很多功能。

安装教程

最官方的安装指南当属官网了,到 https://www.elastic.co/cn/downloads/elasticsearch 直接下载即可。

这里提供了各种系统的下载安装包,目前最新版本是 7.x。

下载完成之后,可以直接参考官网的教程来启动:

其实基本内容就是两步:

  • 解压下载的 zip 压缩文件
  • 直接运行 bin 目录下的 elasticsearch 脚本即可启动

启动之后,Elasticsearch 就会在 9200 端口上运行,这时候我们通过浏览器打开就会看到类似如下的输出:

这就证明 Elasticsearch 安装成功了。

另外 Elasticsearch 还有一个配套的可视化管理工具,叫做 Kibana,安装教程可以参考 https://www.elastic.co/cn/downloads/kibana,安装方式同 Elasticsearch。

安装配置

IntelliJ IDEA 是 java 语言开发的集成环境,在业界被公认为最好的 java 开发工具之一,尤其在智能代码助手、代码自动提示、重构、J2EE 支持、各类版本工具(git、svn 等)、JUnit、CVS 整合、代码分析、 创新的 GUI 设计等方面的功能可以说是超常的。

安装

可以直接到官网 https://www.jetbrains.com/idea/download/ 下载对应的安装包,Windows、Mac、Linux 都有,如图所示:

其中 Ultimate 版本就是专业版,功能齐全而又强大,有 30 天的免费试用,而 Community 就是社区版,功能稍弱,但是永久免费。

其实一般来说,打开一个普通 Java 项目,社区版就足够了。

如果你想用专业版的话,如果 License 过期了,可以自行购买,或者网上找一些免费的 License,另外还可以申请 GitHub 大礼包:https://education.github.com/pack,申请完了之后就可以获得免费订阅了,如图所示:

整个下载安装的过程不再赘述,基本没有什么坑。

安装配置

JEB 是由 PNF 软件(PNF Software)机构开发的一款专业的安卓应用程序的反编译工具,适用于逆向和审计工程,功能非常强大。相比 jadx 来说,JEB 不仅仅支持安卓 apk 的反编译,安卓应用的动态调试,还支持 ARM、MIPS、AVR、Intel-x86、WebAssembly、Ethereum(以太坊)等程序的反编译、反汇编、动态调试等功能,另外还能对一些 PDF 文件进行解析和处理,是一个极其强大的综合性逆向和审计工具。

由于本章的主要内容和安卓逆向相关,所以我们主要关注其和安卓相关的功能。对于安卓应用来说,JEB 主要提供如下功能:

  • 可以对安卓应用程序和 Dalvik(Android 虚拟机,类似 Java 中的 JVM)字节码执行精确和快速的反编译操作。
  • 内置的分析模块可以对高度混淆的代码可以提供虚拟层次化重构,对混淆代码的分析很有帮助。
  • 可以对接 JEB API 来执行一些逆向任务,支持 Java 和 Python 来编写自动化逆向脚本。

JEB 支持 Windows、Linux、Mac 三大平台,其官网地址为 https://www.pnfsoftware.com,目前主要分为三个版本:JEB CE(社区版)、JEB Android(安卓版)、JEB Pro(专业版)。JEB CE 提供了一些基础的功能,如支持 dex 文件的反编译,支持 Intel-x86 的反编译和反汇编,但不支持 Dalvik 字节码的反编译等功能。JEB Android 则更专注于安卓,支持 dex 文件的反编译,也支持 Dalvik 字节码的反编译和反汇编,JEB Pro 则是“完全体”,支持官网所介绍的所有的功能。具体的功能对比可以参考官网的介绍:https://www.pnfsoftware.com/jeb。三个版本中,JEB CE 是免费的,JEB Android 和 JEB Pro 都是收费的,需要购买许可证才可以使用。

安装

如果从官方网站直接下载的话,一些 Android 功能是没法用的,这里建议下载社区大佬们提供的破解版,请移步:https://bbs.pediy.com/thread-268316.htm

另外这里我也准备了一个安装包,链接: https://pan.baidu.com/s/1GyMCbJwjfiNjv9zSBWcoow 提取码: e53q

备用链接(另一个版本的安装包): https://pan.baidu.com/s/1DXTqwWMrLJ-YhPb0zgZKyQ 提取码: 4m49

下载完成,解压后会得到如下的文件目录:

这里有三个运行脚本,分别适配 Windows、Linux、Mac,分别运行 jeb_wincon.bat、jeb_linux.sh、jeb_macos.sh 即可。

如 Mac 下就可以运行:

1
sh jeb_macos.sh

运行之后会出现如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Memory Usage: 981.5M allocated (144.9M used, 836.6M free) - max: 14.2G
JEB 4.3.0.202107131915 (jeb-ce) is starting...
Current directory: /usr/local/etc/jeb
Base directory: /usr/local/etc/jeb
Program directory: /usr/local/etc/jeb/bin
System: Mac OS X 11.5.2 (x86_64) en_CN
Java: Oracle Corporation 1.8.0_282
External plugin loaded: com.pnf.plugin.androidjnihelper.DynamicJNIDetectionPlugin
External plugin loaded: com.pnf.androsig.gen.AndroidSigGenPlugin
External plugin loaded: com.pnf.androsig.apply.andsig.AndroidSigApplyPlugin
External plugin loaded: com.pnf.plugin.oat.OATPlugin
External plugin loaded: com.pnf.plugin.pdf.PdfPlugin
External plugin loaded: com.pnf.diemvm.DiemIdentifier
External plugin loaded: com.pnf.diemvm.DiemDisassemblerPlugin
External plugin loaded: com.pnf.diemvm.DiemDecompilerPlugin
Checking for update...

接着就会弹出 JEB 的窗口,如图所示:

然后就可以使用了。

安装配置

jadx 是一款使用广泛的反编译工具,可以一键把 apk 文件还原成 Java 代码,使用起来简单,功能 强大,还具有一些附加功能可以辅助代码追查。

相关链接

安装方法

Windows

直接到 GitHub 下载对应的 Release 包即可:https://github.com/skylot/jadx/releases。

下载之后直接解压即可。

解压之后会得到一个 bin 目录,进入 bin 目录直接运行 jdax 和 jadx-gui 即可,Windows 可以直接双击 jadx.bat 或 jadx-gui.bat 即可运行。

Mac

对于 Mac 来说,可以直接使用 Homebrew 安装:

1
brew install jadx

Linux

1
sudo pacman -S jadx

更多安装说明可以参考:https://github.com/skylot/jadx。

验证安装

只要 jadx 和 jadx-gui 能正常启动,就证明安装成功了。

安装配置

本节我们了解下 parsel 的安装方式。

相关链接

安装方法

pip 安装

推荐使用 pip3 安装,命令如下:

1
pip3 install parsel

命令执行完毕之后即可完成安装。

验证安装

安装完成之后,可以在 Python 命令行下测试。

1
2
$ python3
>>> import parsel

如果没有错误报出,则证明库已经安装好了。

安装配置

adbutils 是 Python 中 adb 命令行的封装包。

相关链接

安装方法

pip 安装

推荐使用 pip3 安装,命令如下:

1
pip3 install adbutils

命令执行完毕之后即可完成安装。

验证安装

安装完成之后,可以在 Python 命令行下测试,另外确保你的手机已经和电脑通过 USB 或无线的方式连接好了,运行如下代码:

1
2
3
4
import adbutils

adb = adbutils.AdbClient(host="127.0.0.1", port=5037)
print(adb.devices())

如果没有错误报出,而且输出了 Device 相关信息,则证明库已经安装好了。

安装配置

下面是一些群控系统服务网站(不定期更新):

掘金网安卓群控系统:https://www.54nb.com/androids/

侠客科技:https://www.xiake.vip/

智互云客:http://www.zh-auto.org/

智云控:http://www.zhiyunkong.com/

鹰眼:http://ent.mobileanjian.com/

阿云梯:https://www.ayunti.cn/

河马云:http://www.longene.com.cn/

四方来客:http://www.zhiboyk.com/

安装配置

Airtest Project 是由网易游戏推出的一款自动化测试框架,项目构成如下:

  • Airtest:一个跨平台的、基于图像识别的 UI 自动化测试框架,适用于游戏和 App,支持的平台有 Windows、Android 和 iOS,基于 Python 实现。
  • Poco:一款基于 UI 控件识别的自动化测试框架,目前支持 Unity3D、cocos2dx、Android 原生 App、iOS 原生 App 和微信小程序,也可以在其他引擎中自行接入 poco-sdk 来使用,基于 Python 实现。
  • AirtestIDE:提供了一个跨平台的 UI 自动化测试编辑器,内置了 Airtest 和 Poco 的相关插件功能,使用它能够快速简单地编写AirtestPoco代码。
  • AirLab:真机自动化云测试平台,目前提供了 Top 100 手机兼容性测试、海外云真机兼容性测试等服务。
  • 私有化手机集群技术方案:从硬件到软件,提供了企业内部私有化手机集群的解决方案。

总之,Airtest 建立了一个比较完善的自动化测试解决方案,利用 Airtest 我们能实现类似 Appium 一样可见即可爬的爬取,相对 Appium 个人认为更加简单易用。

相关资源

安装

要安装 Airtest,我们可能需要安装多个组件,比如 AirtestIDE、Poco、Airtest 库等。

对于 Airtest IDE 来说,请参考 https://airtest.doc.io.netease.com/IDEdocs/getting_started/AirtestIDE_install/ 里面的说明进行安装。

安装完 Airtest IDE 之后,它还会安装一个 Python 环境,同时该 Python 环境还附带安装了 Airtest Python 库和 Poco Python 库,不过这个 Python 环境被打包在 AirtestIDE 里面,和系统里面装的 Python 并不是同一个,所以,推荐直接使用 pip3 将 Airtest Python 库和 Poco Python 库安装到系统的 Python 环境下。

Airtest Python 库的安装命令如下:

1
pip3 install airtest

Poco Python 库的安装命令如下:

1
pip3 install pocoui

安装完成之后,可以在 AirtestIDE 中把默认 Python 环境更换成系统的 Python 环境,而不再是 AirtestIDE 附带的 Python 环境,打开 AirtestIDE 菜单的选项 - 设置,可以看到如下配置:

可以看到这里有一个选项叫做 “自定义 Python.exe 路径”,将其修改为系统的 Python 路径即可,具体的设置方法可以进一步参考:https://airtest.doc.io.netease.com/IDEdocs/3.4run_script/0_run_script/#4

安装好了 Airtest IDE、Airtest 和 Poco 的 Python 库之后,最后我们还需要准备一台 Android 真机或者模拟器,如果是真机还需要通过 USB 和 PC 相连,确保 adb 能够正常连接到手机,具体的设置方法可以参考:https://airtest.doc.io.netease.com/tutorial/1_quick_start_guide/#_4

安装配置

简单的说 Node.js 就是运行在服务端的 JavaScript。

Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台。

Node.js 是一个事件驱动 I/O 服务端 JavaScript 环境,基于 Google 的 V8 引擎,V8 引擎执行 Javascript 的速度非常快,性能非常好。

如果你是一个前端程序员,你不懂得像 PHP、Python 或 Ruby 等动态编程语言,然后你想创建自己的服务,那么 Node.js 是一个非常好的选择。

Node.js 是运行在服务端的 JavaScript,如果你熟悉 Javascript,那么你将会很容易的学会 Node.js。

相关链接

安装方法

由于 Node.js 频繁更新,请直接移步 Node.js 中文网介绍查看安装说明即可:http://nodejs.cn/learn/how-to-install-nodejs。

另外,个人也非常推荐使用 nvm 来安装 Node.js,有了 nvm,我们可以方便地管理多个 Node.js 版本,其实有点类似于 Python 虚拟环境的感觉,具体的安装说明可以参考:https://github.com/nvm-sh/nvm。

安装配置

本文介绍代理软件的配置,由于内容可能相对敏感,所以这里仅提供外链。

个人比较推荐的是:konan 点 ml,里面有很多套餐,同时教你怎么在各个平台(Windows、Mac、Linux、Android、iOS)上配置和运行对应的代理软件。

运行代理软件后会在本机创建 HTTP 或 SOCKS 代理服务,所以代理地址一 般是 127.0.0.1:<port> 这样的格式,不同代理软件使用的端口可能不同。

我的本机上安装着一个代理软件,它会在 7890 端口上创建 HTTP 代理服务,在 7891 端口上创建 SOCKS 代理服务,因此 HTTP 代理地址为 127.0.0.1:7890,SOCKS 代理地址为 127.0.0.1:7891,只要 设置了这个代理,就可以成功将本机 IP 切换到代理软件连接的服务器的 IP。

安装配置

Pillow 是 Python 的一个支持图像处理的库,本节我们了解下 Pillow 的安装方式。

相关链接

安装方法

pip 安装

推荐使用 pip3 安装,命令如下:

1
pip3 install Pillow

命令执行完毕之后即可完成安装。

具体的 Python 版本支持可以参考 https://pillow.readthedocs.io/en/latest/installation.html 的说明,如图所示:

验证安装

安装完成之后,可以在 Python 命令行下测试。

1
2
$ python3
>>> import pillow

如果没有错误报出,则证明库已经安装好了。

安装配置

本节我们了解下 opencv-python 的安装方式。

相关链接

安装方法

pip 安装

推荐使用 pip3 安装,命令如下:

1
pip3 install opencv-python

命令执行完毕之后即可完成安装。

另外,如果想要额外安装一些 contrib 模块的话,可以选择全量安装:

1
pip3 install opencv-contrib-python

更多安装说明可以参考:https://github.com/opencv/opencv-python。

验证安装

安装完成之后,可以在 Python 命令行下测试。

1
2
$ python3
>>> import cv2

如果没有错误报出,则证明库已经安装好了。

安装配置

PyTorch 是当今非常火爆的深度学习框架。

相关链接

安装方法

PyTorch 适配的平台有很多,官方也提供了安装教程,可以参考 https://pytorch.org/get-started/locally/,

打开之后可以看到有好多选项配置,让我们选择我们当前的环境是怎样的,如图所示:

比如这里我们可以选择版本、操作系统、包工具、开发语言、GPU 环境等等,选择之后,最后就会显示一条命令,比如这里的命令就是:

1
pip3 install torch==1.9.1+cu111 torchvision==0.10.1+cu111 torchaudio==0.9.1 -f https://download.pytorch.org/whl/torch_stable.html

这样的话我们只需要运行这条命令,那就可以在 Linux 上使用 pip 安装适配 CUDA 11.1 的 PyTorch 库了。

更详细的安装配置可以参考:https://pytorch.org/get-started/locally/。

安装配置

Playwright 是微软开源的自动化测试工具,也可以用作网络爬虫。

相关链接

安装方法

pip 安装

推荐使用 pip3 安装,命令如下:

1
2
3
pip3 install --upgrade pip
pip3 install playwright
playwright install

命令执行完毕之后即可完成安装,其中最后一条命令,Playwright 会完成一些初始化的工作,比如下载必要的浏览器和配置对应驱动、环境变量等。

conda 安装

也可以使用 conda 安装,安装命令如下:

1
2
3
4
conda config --add channels conda-forge
conda config --add channels microsoft
conda install playwright
playwright install

效果是一样的。

验证安装

安装完成之后,可以在 Python 命令行下测试。

1
2
$ python3
>>> import playwright

如果没有错误报出,则证明库已经安装好了。

安装配置

MongoDB 是由 C++ 语言编写的非关系型数据库,是一个基于分布式文件存储的开源数据库系统,其内容存储形式类似 Json 对象,它的字段值可以包含其他文档,数组及文档数组,非常灵活。

MongoDB 支持多种平台,包括 Windows、Linux、Mac OS、Solaris 等,在其官方网站均可找到对应的安装包,https://www.mongodb.com/download-center

本节我们来看下它的安装过程。

相关链接

安装方法

Windows 下的安装

直接在官网下载安装包即可,链接为:https://www.mongodb.com/try/download/community,页面如图所示:

直接点击 Download 下载 msi 安装包即可。

下载完成之后双击开始安装,如图所示:

后面的安装模式选择 Complete 即可,如图所示:

点击之后可以看到一些 MongoDB 安装配置,如 data 文件夹、log 文件夹都在哪里,还有是否把 MongoDB 安装成系统服务,如图所示:

一直点击下一步安装即可。

安装完毕之后 MongoDB 也会被注册成一个 Windows 服务,而且已经启动,如图所示:

这里我们可以控制服务的开关,即 MongoDB 服务的开关。

这样 Windows 下 MongoDB 配置就完成了。

Linux 下的安装

完整的安装教程请参考:https://docs.mongodb.com/manual/administration/install-on-linux/,如下内容仅作参考。

在这里以 MongoDB 5.0 为例说明 MongoDB 的安装过程。

Ubuntu

首先导入 MongoDB 的 GPG Key:

1
wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | sudo apt-key add -

随后创建 apt-get 源列表,各个系统版本对应的命令如下:

  • Ubuntu 20.04
1
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-5.0.list
  • Ubuntu 18.04
1
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/5.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-5.0.list

随后更新 apt-get 源:

1
sudo apt-get update

之后安装 MongoDB 即可:

1
sudo apt-get install -y mongodb-org

安装完成之后运行 MongoDB,命令如下:

1
sudo systemctl start mongod

运行命令之后 MongoDB 就在 27017 端口上运行了,数据文件会保存在 /data/db 路径下。

一般我们在 Linux 上配置 MongoDB 都是为了远程连接使用的,所以在这里还需要配置一下 MongoDB 的远程连接和用户名密码:

接着我们进入到 MongoDB 命令行:

1
mongo --port 27017

现在我们就已经进入到 MongoDB 的命令行交互模式下了,在此模式下运行如下命令:

1
2
3
4
5
6
7
8
9
10
11
12
> use admin
switched to db admin
> db.createUser({user: 'admin', pwd: 'admin123', roles: [{role: 'root', db: 'admin'}]})
Successfully added user: {
"user" : "admin",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}

这样我们就创建了一个用户名为 admin,密码为 admin123 的用户,赋予最高权限。

随后需要修改 MongoDB 的配置文件,

执行如下命令:

1
sudo vi /etc/mongod.conf

修改 net 部分为:

1
2
3
net:
port: 27017
bindIp: 0.0.0.0

这样配置后 MongoDB 可被远程访问。

另外还需要添加如下权限认证配置,直接添加如下内容到配置文件:

1
2
security:
authorization: enabled

配置完成之后我们需要重新启动 MongoDB 服务,命令如下:

1
sudo service mongod restart

这样远程连接和权限认证就配置完成了。

CentOS、RedHat

首先添加 MongoDB 源:

1
sudo vi /etc/yum.repos.d/mongodb-org.repo

修改为如下内容保存:

1
2
3
4
5
6
[mongodb-org-5.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/5.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-5.0.asc

然后执行 yum 命令安装:

1
sudo yum install mongodb-org

启动 MongoDB 服务:

1
sudo systemctl start mongod

停止和重新加载 MongoDB 服务:

1
2
sudo systemctl stop mongod
sudo systemctl reload mongod

有关远程连接和认证配置可以参考上文,方式是相同的。

更多 Linux 发行版的 MongoDB 安装方式可以参考官方文档:https://docs.mongodb.com/manual/administration/install-on-linux/。

Mac 下的安装

完整安装说明请参考:https://docs.mongodb.com/manual/tutorial/install-mongodb-on-os-x/,如下内容仅作参考。

首先确保一些依赖库已经正确安装了,运行如下命令:

1
xcode-select --install

推荐使用 Homebrew 安装,执行 brew 命令即可:

1
2
brew tap mongodb/brew
brew install mongodb-community@5.0

然后创建一个新文件夹 /data/db,用于存放 MongoDB 数据。

启动 MongoDB 服务:

1
brew services start mongodb-community@5.0

这样就启动了 MongoDB 服务。

停止、重启 MongoDB 服务的命令:

1
2
brew services stop mongodb-community@5.0
brew services restart mongodb-community@5.0

可视化工具

在这里推荐一个可视化工具 RoboMongo/Robo 3T,使用简单,功能强大,官方网站:https://robomongo.org/,三大平台都有支持,下载链接:https://robomongo.org/download

另外还有一个简单易用的可视化工具,Studio 3T,同样具有方便的图形化管理,官方网站:https://studio3t.com,同样支持三大平台,下载链接:https://studio3t.com/download/

安装配置

Splash 是一个 JavaScript 渲染的工具,本节来介绍一下它的安装方式。

准备工作

Splash 建议的安装方式是通过 Docker,安装是通过 Docker 安装,在这之前请确保已经正确安装好了 Docker,可以参考:https://setup.scrape.center/docker。

安装

有了 Docker,只需要一键启动 Splash 即可,命令如下:

1
docker run -p 8050:8050 scrapinghub/splash

安装完成之后会有类似的输出结果:

这样就证明 Splash 已经在 8050 端口上运行了。

这时我们打开:http://localhost:8050 即可看到 Splash 的主页,如图所示:

当然 Splash 也可以直接安装在远程服务器上,我们在服务器上运行以守护态运行 Splash 即可,命令如下:

1
docker run -d -p 8050:8050 scrapinghub/splash

在这里多了一个 -d 参数,它代表将 Docker 容器以守护态运行,这样在中断远程服务器连接后不会终止 Splash 服务的运行。

完毕!

安装配置

MySQL 是一个轻量级的关系型数据库,以表的形式来存储数据,本节我们来了解下它的安装方式。

相关链接

Windows 下的安装

对于 Windows 来说,最安全稳妥的方式就是直接到官网下载安装包进行安装。可以访问官方网站下载,https://dev.mysql.com/downloads/mysql/,如图所示:

点击最大的 MySQL Installer 即可,然后选择第二个选项 - mysql-installer-community-8.0.26.0.msi 下载即可,如图所示:

此时会要求登录 MySQL 的账号,这里可以登录或者选择直接下载,如图所示:

下载之后会得到一个 msi 后缀的安装文件,直接双击运行安装,直接选择默认选项点击下一步安装即可,如图所示:

这里直接选择默认选项即可,然后点下一步。

下一页需要确认下需要安装的内容,如图所示:

保持默认配置即可,然后点击 Execute 即可。

安装完成之后 MySQL Installer 会引导我们进行一些配置,如图所示:

此页面需要配置一些网络环境和端口,保持默认即可,点击下一步。

下一步是使用怎样的密码加密方式,如图所示:

这里也是使用默认配置即可,可以点击下一步。

下一步就是配置用户名和密码,这里我们可以配置 Root 账户的密码,也可以自定义用户来配置,如图所示:

输入密码之后,点击下一步即可。

接下来就是服务的配置,这里默认配置是把 MySQL 服务配置成 Windows 服务中,而且在每次系统启动的时候都自动启动 MySQL 服务,如图所示:

如果我们想要每次开机的时候都自动启用 MySQL 服务,那我们可以勾选上 Start the MySQL Server at System Startup,否则勾选,配置好了之后点击下一步即可。

最后一步就是应用刚才的服务,使得服务生效,如图所示:

这里我们直接点击 Execute 即可。

安装之后我们会发现刚才还附带安装了一个 MySQL Workbench,就是 MySQL 可视化管理的客户端,如图所示:

这里可以发现已经添加了一个本地的 MySQL 服务的连接,双击即可连接。

连接之后我们还可以选中某个数据库的某个表,选择查看数据的选项 Select Rows,查看表中中的前 100 条数据,这样数据就被查询出来了,如图所示:

安装完成之后我们可以在电脑-管理-服务页面开启和关闭 MySQL 服务,如图所示:

如果启动了 MySQL 服务,那么我们就可以使用它来进行数据存储了。

Linux 下的安装

下面仍然分不同平台进行介绍。

Ubuntu、Debian、Deepin

直接使用 apt-get 命令即可下载安装:

1
2
sudo apt-get update
sudo apt-get install -y mysql-server mysql-client

在安装过程中会提示输入用户名密码,输入之后等待片刻即可完成安装。

启动、关闭、重启 MySQL 服务命令:

1
2
3
sudo service mysql start
sudo service mysql stop
sudo service mysql restart

CentOS、RedHat

完整的安装说明可以参考:https://www.digitalocean.com/community/tutorials/how-to-install-mysql-on-centos-7

以 MySQL 5.7 的 Yum 源为例,如果需要更高版本可以另寻,安装命令如下:

1
2
3
wget https://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm
sudo rpm -ivh mysql-community-release-el7-5.noarch.rpm
yum install -y mysql mysql-server

运行如上命令即可完成安装,初始密码为空。接下来需要启动 MySQL 服务。

启动 MySQL 服务命令:

1
sudo systemctl start mysqld

停止、重启命令:

1
2
sudo systemctl stop mysqld
sudo systemctl restart mysqld

以上我们就完成了 Linux 下 MySQL 的安装,安装完成之后可以修改密码,可以执行如下命令:

1
mysql -uroot -p

输入密码后进入 MySQL 命令行模式。

1
2
3
use mysql;
UPDATE user SET Password = PASSWORD('newpass') WHERE user = 'root';
FLUSH PRIVILEGES;

命令中 newpass 即为修改的新的 MySQL 密码,请自行替换。

由于 Linux 一般会作为服务器使用,为了使得 MySQL 可以被远程访问,我们需要修改 MySQL 的配置文件,配置文件路径一般为 /etc/mysql/my.cnf。

如使用 vi 进行修改的命令如下:

1
vi /etc/mysql/my.cnf

取消此行的注释:

1
bind-address = 127.0.0.1

此行限制了 MySQL 只能本地访问而不能远程访问,取消注释即可解除此限制。

修改完成之后重启 MySQL 服务,这样 MySQL 就可以被远程访问了。

到此为止,Linux 下安装 MySQL 的过程结束。

Mac 下的安装

推荐使用 Homebrew 安装,执行 brew 命令即可。

1
brew install mysql

启动、停止、重启 MySQL 服务的命令:

1
2
3
sudo mysql.server start
sudo mysql.server stop
sudo mysql.server restart

Mac 一般不会作为服务器使用,如果要想取消本地 host 绑定,同样修改 my.cnf 文件,然后重启服务即可。