介绍

了解 LinkedIn 在抓取数据时如何阻止自动化而臭名昭著,您如何确保成功为您的企业获取这些备受追捧的专业个人资料数据?

如果这是您希望解决的主要痛点,那么您就可以享受到了。

Crawlbase 充分意识到 LinkedIn 数据爬行带来的丰富机会。 事实上,作为互联网抓取的先驱,Crawlbase 专门获取 LinkedIn 数据,并拥有独特的算法,可确保成功的抓取体验,专为 LinkedIn 数据量身定制。

了解项目范围

本指南将演示如何使用 Flask 构建弹性回调服务器。 该服务器将充当 webhook 爬虫库 Crawler,促进 LinkedIn 用户个人资料的异步检索。 重点是解析“体验”部分并将其保存在 MySQL 数据库中。 此过程优化了基本数据的收集,可应用于:

  1. 人才搜寻和招聘
  2. 人力资源和员工发展
  3. 市场情报与分析
  4. 预测数据分析
  5. 人工智能和机器学习算法

处理此类数据时,尊重 LinkedIn 的使用条款和隐私准则至关重要。 Crawlbase 严格禁止从 LinkedIn 或任何其他网站提取私人数据。 此处的示例仅基于可公开访问的数据,旨在用于教育目的。

让我们开始。

目录:

第一部分:准备环境

A。 创建 Crawlbase 帐户并激活 LinkedIn 爬网
b. 设置 MySQL 数据库
C。 文件和目录结构
d. 用Python构建虚拟环境
e. 如何获取 LinkedIn 个人资料列表

第二部分:为项目编写脚本

A。 使用 SQLAlchemy 创建 ORM 定义以与数据库交互
b. 向 Crawlbase 发送请求的脚本 Crawler
C。 创建 Flask 回调服务器
d. 用于检索爬网数据并将其存储在数据库中的脚本

第三部分:执行脚本

A。 使用 Ngrok 启动本地隧道服务
b. 运行回调服务器
C。 测试回调服务器
d. 配置 Crawlbase Crawler 使用您的回调 URL
e. 运行处理器
F。 开始爬行

第四部分: Crawler 监控

第六部分:结论

第六部分:常见问题

第一部分:准备环境

A. 创建 Crawlbase 帐户并激活 LinkedIn 爬行

  1. 首先访问 Crawlbase 网站并 注册新账号.
  2. LinkedIn 协议页面 阅读并接受条款。
  3. 添加您的账单详细信息,方法是转至 帐单信息设置.

B. 设置 MySQL 数据库

我们将使用 MySQL,因为它是一种流行的关系数据库管理系统,广泛用于各种应用程序。 在此示例中,我将使用 MySQL 版本 8。如果您的计算机上尚未安装此版本,请转到 MySQL官方安装手册.

安装完成后,打开MySQL命令行客户端。 系统将提示您输入 MySQL root 用户的密码。 输入密码后,您将进入MySQL命令行界面。 然后,您可以执行以下命令行。

  1. 创建一个新用户
1
CREATE USER '链接爬虫'@'本地主机' 已识别 BY 'linked1nS3cret';

该代码创建一个名为的新 MySQL 用户 linkedincrawler 用密码 linked1nS3cret,仅限于从同一台计算机 (localhost) 连接。

  1. 建立资料库
1
CREATE 数据库linkedin_crawler_db;

该数据库将是一个空容器,可以存储表、数据和其他对象。

  1. 授予权限
1
 全部 特权 ON linkedin_crawler_db。* TO '链接爬虫'@'本地主机';

这将授予我们的用户对新创建的数据库的完全特权和权限。

  1. 设置当前数据库
1
使用linkedin_crawler_db;

这将选择我们的数据库并将所有指令定向到该数据库。

  1. 现在,让我们在当前选定的数据库中创建三个表: crawl_requests, linkedin_profileslinkedin_profile_experiences.

这款 crawl_requests 将成为主表,充当跟踪整个异步抓取过程的机制。

在此表中,我们将有 3 列: url, status, crawlbase_rid.

这款 status 列可以具有以下三个值之一 - waiting, receivingprocessed。 这些状态的目的将在稍后详细说明。

1
2
3
4
5
6
CREATE  IF 不是 EXISTS `爬行请求` (
`id` INT 自动递增 小学 键,
`url` 文本 不是 ,
`状态` 变量(30) 不是 ,
`crawlbase_rid` 变量(255) 不是
);

然后我们创建数据库索引以提高查询性能。

1
2
3
CREATE 索引 `idx_crawl_requests_status` ON `crawl_requests` (`status`);
CREATE 索引 `idx_crawl_requests_crawlbase_rid` ON `crawl_requests` (`crawlbase_rid`);
CREATE 索引 `idx_crawl_requests_status_crawlbase_rid` ON `crawl_requests` (`status`, `crawlbase_rid`);

对于最后 2 个表,它将允许您存储已爬网的 LinkedIn 个人资料及其相关详细信息的结构化信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
CREATE  IF 不是 EXISTS `linkedin_profiles` (
`id` INT 自动递增 小学 键,
`crawl_request_id` INT 不是 ,
`标题` 变量(255),
`标题` 变量(255),
`摘要`文本,

国外 KEY (`爬行请求 ID`) 参考文献: `crawl_requests`(`id`)
);

CREATE IF 不是 EXISTS `linkedin_profile_experiences` (
`id` INT 自动递增 小学 键,
`linkedin_profile_id` INT 不是 ,
`标题` 变量(255),
`公司名称` 变量(255),
`描述`文本,
`is_current` 位 不是 DEFAULT 0,

国外 KEY (`linkedin_profile_id`) 参考文献: `linkedin_profiles`(`id`)
);

要查看您在 MySQL 数据库中创建的表,请在 MySQL 命令行界面或 MySQL 客户端工具中使用 SQL 查询。

MySQL 命令行界面

C. 文件和目录结构

在 Python 中设置环境时组织文件非常重要。 确保它们都保存在同一项目目录下,如下所示:

文件和目录结构

D. 用Python构建虚拟环境

虚拟环境是一个隔离的空间,您可以在其中安装 Python 包,而不会影响系统范围内的 Python 安装。 管理不同项目的依赖关系很有用。

在这个项目中我们将使用 Python的3。 确保下载并安装适当的版本。

可选 吉特·巴什(Git Bash) 或终端执行以下命令。

1
PROJECT_FOLDER$ python3 -m venv .venv

创建虚拟环境后,您需要激活它。

1
PROJECT_FOLDER$ 。 .venv/bin/激活

在项目文件夹中创建一个文本文件并将其另存为 PROJECT_FOLDER/requirements.txt。 该文件应包含我们的项目所依赖的以下 Python 包。

1
2
3
4
5
长颈瓶
mysql-连接器-python
皮亚姆尔
要求
SQLAlchemy的

使用以下命令安装依赖项 pip 命令。

1
PROJECT_FOLDER$ pip install -r requests.txt

在同一目录下,创建一个名为 PROJECT_FOLDER/settings.yml 它将作为你的 Crawlbase (TCP) 令牌的占位符,并且 Crawler 名称。

1
2
令牌: < >
搜寻器: 我的爬虫名称

E. 如何获取 LinkedIn 个人资料列表

要获取 LinkedIn 个人资料 URL 列表,您通常需要从不同来源(例如搜索结果、连接或公共个人资料)收集这些 URL。 您可以通过以下几种方式获取 LinkedIn 个人资料 URL:

  1. 手动采集:
  • 您可以手动访问 LinkedIn 个人资料并从网络浏览器的地址栏中复制 URL。 此方法适用于配置文件数量较少的情况。
  1. 领英搜索结果:
  • 使用 LinkedIn 的搜索功能根据特定条件(例如职位、地点、行业)查找个人资料。
  • 复制搜索结果中列出的配置文件的 URL。
  1. 连接的个人资料:
  • 如果您在 LinkedIn 上与某人建立了联系,您可以访问他们的联系列表并从那里提取个人资料 URL。
  1. 第三方API:
  • 您可以利用 Crawlbase 构建一个单独的抓取工具来自动收集 LinkedIn URL。 我们可能会在以后的文章中对此进行介绍,所以请注意。

为了本文的目的,我们提供了要抓取的 LinkedIn URL 列表。 默认情况下,我们已经配置了文本文件 LinkedIn 上最受关注的 5 名人物.

该文件位于 PROJECT_FOLDER/urls.txt.

请注意: 每一行对应一个有效的 URL。 如果您有现成的 URL,您可以编辑此文本文件并将它们添加到列表中。

第二部分:为项目编写脚本

A. 使用 SQLAlchemy 创建 ORM 定义以与数据库交互

现在,我们必须构建一个脚本来处理 MySQL 数据库中的 LinkedIn 相关数据。 该脚本将首先从 SQLAlchemy 导入必要的模块以及类型提示的键入模块。

出于演示目的,我们将此脚本保存在 PROJECT_FOLDER/lib/database.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
 键入         进口 列表
炼金术 进口 外键
炼金术 进口 创建引擎
sqlalchemy.orm 进口 声明性基础
sqlalchemy.orm 进口 时间
sqlalchemy.orm 进口 映射
sqlalchemy.orm 进口 映射列
sqlalchemy.orm 进口 关系

基值(声明性基础):
通过

抓取请求(基值):
__表名__ = '爬行请求'

id: 映射[INT] = 映射_列(主键=)
url: 映射[STR]
状态:已映射[STR]
crawlbase_rid:映射[STR]
linkedin_profile:映射[“领英个人资料”] = 关系(back_populates='爬行请求')

领英个人资料(基值):
__表名__ = 'linkedin_profiles'

id: 映射[INT] = 映射_列(主键=)
标题:映射[STR]
标题:映射[STR]
摘要:映射[STR]
crawl_request_id: 映射[INT] = 映射_列(外键('crawl_requests.id'))
crawl_request:映射[“抓取请求”] = 关系(back_populates='linkedin_个人资料')
经验:映射[列表[“Linkedin个人资料体验”]] = 关系(back_populates='linkedin_个人资料')

LinkedIn个人资料经历(基值):
__表名__ = 'linkedin_profile_experiences'

id: 映射[INT] = 映射_列(主键=)
标题:映射[STR]
公司名称:映射[STR]
描述:映射[STR]
is_current:映射[布尔]
linkedin_profile_id:映射[INT] = 映射_列(外键('linkedin_profiles.id'))
linkedin_profile:映射[“领英个人资料”] = 关系(back_populates=“经历”)

DEF 创建数据库会话():
连接字符串 = 'mysql+mysqlconnector://linkedincrawler:linked1nS3cret@localhost:3306/linkedin_crawler_db'
引擎 = create_engine(connection_string, echo=)
回报 会话(引擎)

此代码提供了创建数据库交互会话的功能。 请注意,我们将提供的脚本假设您已经安装了必要的库,并且 MySQL 服务器正在使用指定的连接详细信息运行。

B. 向 Crawlbase 发送请求的脚本 Crawler

爬行基地 Crawler 在使用回调 URL 的推送系统中异步运行。当您向 Crawler,它分配一个 唯一的RID 到每个请求。 Crawler 内部执行抓取,直到 成功响应 获得。 随后,此响应将传输回您指定的 Webhook,使您能够处理数据并将其存储在数据库中。

欲了解更多详情,您可以查看 完整的文档 爬行基地 Crawler.

该脚本首先导入必要的模块,包括用于发出 HTTP 请求的 requests、用于 URL 编码的 urllib.parse、用于处理 JSON 数据的 json 以及用于处理 JSON 解码错误的 JSONDecodeError。

出于演示目的,我们将此脚本保存在 PROJECT_FOLDER/crawl.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
进口 要求
进口 urllib.parse
进口 JSON
JSON 进口 JSON解码错误
库工具 进口 日志
库工具 进口 加载设置
库数据库 进口 抓取请求
库数据库 进口 创建数据库会话

crawlbase_settings = load_settings()

crawlbase_token=crawlbase_settings.get('令牌')
crawlbase_crawler=crawlbase_settings.get(“爬行者”)

if crawlbase_token is 没有 or crawlbase_token.strip() == '':
打印('------------------------------------------------- -')
打印('请在 settings.yml 中设置您的 Crawlbase 令牌')
打印('------------------------------------------------- -')
出口()

if crawlbase_crawler is 没有 or crawlbase_crawler.strip() == '':
打印('------------------------------------------------- ----')
打印('请在settings.yml中设置您的Crawlbase爬虫')
打印('------------------------------------------------- ----')
出口()

linked_in_profile_urls = 打开('urls.txt', 'r').readlines()

if LEN(linked_in_profile_urls) == 0:
打印('------------------------------------------------- -------------------------------------------------- --')
打印('没有可用的网址。 请将网址填充到“urls.txt”,并用换行符分隔。)
打印('------------------------------------------------- -------------------------------------------------- --')
出口()

日志(“开始爬行……”)

爬行库_api_url = 'https://api.crawlbase.com?token={0}&callback=true&crawler={1}&url={2}&autoparse=true'

会话 = create_database_session()

网址 in linked_in_profile_urls:
url = url.strip()
编码的 url = urllib.parse.quote(url, safe='')
api_url =crawlbase_api_url。格式(crawlbase_token、crawlbase_crawler、encoded_url)

日志(f'请求抓取 {网址}')

尝试:
响应 = requests.get(api_url)
json_response = json.loads(response.text)
crawlbase_rid = json_response[‘摆脱’]
crawl_request = CrawlRequest(url=url,crawlbase_rid=crawlbase_rid,status='等待')
会话.add(crawl_request)
会话.commit()
JSON解码错误:
日志(f'解码 json 响应时发生错误\n{响应.文本}')
:
日志(f'抓取时发生未知错误 {网址}')

日志(“爬行完毕。”)

该代码将从以下位置读取 URL PROJECT_FOLDER/urls.txt 并将每个 URL 发送到 Crawlbase API 进行抓取,然后 API 将返回一个请求 ID,例如 {”rid”: 12341234}。 该代码将创建一个新的行条目来将 RID 存储在我们的 crawl_requests 表的状态为 waiting.

请注意,我们必须插入相应的 crawlbase_tokencrawlbase_crawler 在此脚本中的名称,我们将在稍后的指南中解决。

C. 创建 Flask 回调服务器

长颈瓶 是一个用 Python 编写的微型 Web 框架,我们将用它来创建回调服务器。

确保您的回调能够执行 base64 解码和 gzip 解压缩。这很重要,因为 Crawler 引擎将使用带有 gzip 压缩和 base64 编码的 POST 方法将数据传输到您的回调端点。

出于演示目的,我们将此脚本保存在 PROJECT_FOLDER/callback_server.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
进口 GZIP
烧瓶 进口 长颈瓶
烧瓶 进口 json化
烧瓶 进口 请求
库工具 进口 日志
库数据库 进口 抓取请求
库数据库 进口 创建数据库会话

app = Flask(__ name__)
会话 = create_database_session()

@app.route('/crawlbase_crawler_callback',方法=['POST'])
DEF crawlbase_crawler_callback():
crawlbase_rid = request.headers.get(‘摆脱’)
content_encoding = request.headers.get(“内容编码”)
原始状态 = request.headers.get(“原始状态”)
if (而不去 原始状态 is 没有):
原始状态= INT(original_status.split(',')[0])
crawlbase_status = request.headers.get(“PC 状态”)
if (而不去 爬网状态 is 没有):
爬网状态= INT(crawlbase_status.split(',')[0])

if 爬行库_rid is 没有:
日志(f“未设置 Crawlbase rod。”)
回报 ('', 204)

if 爬行库_rid == '虚拟请求':
日志('回调服务器正在工作')
回报 ('', 204)

if 爬网状态!= 200:
日志(f“Crawlbase 状态不是 200。”)
回报 ('', 204)

if 原始状态!= 200:
日志(f'原始状态不是 200。')
回报 ('', 204)

crawl_request_does_not_exist = session.query(CrawlRequest).filter_by(crawlbase_rid=crawlbase_rid, status='等待')。第一的() is 没有

if crawl_request_does_not_exist:
日志(f'No Crawlbase 摆脱 {爬行基地} 发现状态为“正在等待”。)
回报 ('', 204)

crawl_request = session.query(CrawlRequest).filter_by(crawlbase_rid=crawlbase_rid, status='等待').标量()

正文=请求.数据
if 内容编码== ‘gzip’:
尝试:
正文 = gzip.解压缩(正文)
操作系统错误:
通过

- 打开(f'./数据/{爬行基地}.json', 'wb') as f:
f.write(正文)

抓取请求.状态= '已收到'
会话.commit()

日志(f'Crawlbase 摆脱 {爬行基地} 已成功收到。)

回报 ('', 201)

if __名字__ == '__主要__':
app.run()

此代码设置了一个 Flask 应用,其中包含一个路由来处理来自 Crawlbase 的回调 Crawler。请注意 Crawlbase Crawler 将 RID 信息放入名为 rid.

此外,此代码将检查我们的 crawl_requests 具有相同 RID 的表 waiting 状态,否则请求将被忽略。

它还确保请求标头 Original-StatusPC-Status 是 HTTP 200 OK 成功状态响应代码。

一旦它从 Crawler,它将被处理(解码和解压缩)并保存在数据文件夹中,然后将 RID 的状态更新为 received.

D. 检索爬取数据并存储在数据库中的脚本

这段代码承担了定期监控crawl_requests表中RID状态的任务。 当它检测到已收到状态时,它会启动数据处理以填充 linkedin_profiles 和 linkedin_profiles_experiences 表。 完成后,它将 RID 状态更新为已处理。

出于演示目的,我们将此脚本保存在 PROJECT_FOLDER/process.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
进口 JSON
进口 附表:
进口
库工具 进口 日志
库工具 进口 是可迭代的
库数据库 进口 抓取请求
库数据库 进口 领英个人资料
库数据库 进口 LinkedIn个人资料经历
库数据库 进口 创建数据库会话

SCHEDULE_INTERVAL_IN_SECONDS = 60
RECORDS_COUNT_LIMIT_PER_PROCESSING = 10

DEF 过程():
会话 = create_database_session()
receive_crawl_requests = session.query(CrawlRequest).filter_by(status='已收到').limit(RECORDS_COUNT_LIMIT_PER_PROCESSING)。所有()

if LEN(收到的抓取请求) == 0:
日志(“没有收到要处理的抓取请求。”)
其他:
抓取请求 in 收到的抓取请求:
日志(f'Processing Crawlbase 删除 {crawl_request.crawlbase_rid} 带网址 {爬行请求.url}.')

f = 打开(f'./数据/{crawl_request.crawlbase_rid}.json')
数据 = json.load(f)

标题=数据.get('标题')
标题=数据.get('标题')
摘要 = data.get('概括')
总结= '\n'.join(摘要) if is_iterable(摘要) 其他 没有

linkedin_profile = LinkedinProfile(标题=标题,标题=标题,摘要=摘要)
linkedin_profile.crawl_request_id = 爬行请求。id
会话.add(linkedin_profile)

经验 = (data.get('经验') 数据.获取('经验')。得到('经验列表')) or []
丰富的行业经验和创意思维 in 经验:
标题=经验.get('标题')
公司名称 = 经验.get('公司') 经验.获取('公司')。得到(“名称”)
描述 = experience.get('描述')
描述 = '\n'.join(描述) if is_iterable(描述) 其他 没有
is_current = experience.get('当前位置')==

linkedin_profile_experience = LinkedinProfileExperience(
标题=标题,
公司名称=公司名称,
描述=描述,
is_current=is_current
)
linkedin_profile_experience.linkedin_profile = linkedin_profile
session.add(linkedin_profile_experience)

抓取请求.状态= '处理'

会话.commit()

DEF 处理并重新安排():
过程()
调度程序.enter(SCHEDULE_INTERVAL_IN_SECONDS, 1、流程和重新安排)

if __名字__ == '__主要__':
调度程序 = sched.scheduler(time.monotonic, time.sleep)
process_and_reschedule()
调度程序.run()

第三部分:执行脚本

A. 使用 Ngrok 启动本地隧道服务

恩格罗克 是一个创建到本地主机的安全隧道的工具,允许您暂时将本地托管的 Web 应用程序公开到互联网。

使用 Ngrok 创建一个指向本地托管应用程序的临时公共 URL。这将允许我们使用 Flask Callback 服务器作为 Crawlbase 的 webhook Crawler.

1
$ ngrok http 5000

一旦执行,获取公共 URL,我们稍后将使用它来创建我们的 Crawler.

恩格罗克

注意:我们需要将 ngrok 指向端口 5000 作为我们的 Flask 应用程序 callback_server.py 将默认为同一端口。

B. 运行回调服务器

现在 Ngrok 已经初始化,我们可以运行回调服务器来捕获 RID 并从 Crawlbase 爬取内容。

1
PROJECT_FOLDER$ pythoncallback_server.py

根据我们的代码,这是处理回调的完整路由:

https://400d-120-29-87-188.ngrok.io/crawlbase_crawler_callback

C. 测试回调服务器

我们必须确保回调服务器按预期工作并且可以传递 爬网要求。 为此,您可以执行以下代码片段并观察结果:

1
$ 卷曲 -i -X POST 'http://localhost:5000/crawlbase_crawler_callback' -H 'RID:虚拟请求' -H '接受:应用/ JSON' -H '内容类型:gzip/json' -H “用户代理:Crawlbase 监控机器人 1.0” -H '内容编码:gzip' --数据二进制 '"\x1F\x8B\b\x00+\xBA\x05d\x00\x03\xABV*\xCALQ\xB2RJ)\xCD\xCD\xAD,J-,M-.Q\xD2QJ\xCAO\xA9\x04\x8A*\xD5\x02\x00L\x06\xB1\xA7 \x00\x00\x00' --压缩

本篇 curl 命令将使用自定义 HTTP 标头向您的回调 URL 发出 POST 请求 'HTTP_RID' 设置 'test'.

成功执行后,您应该收到如下所示的相同响应:

[app][2023-08-10 17:42:16] Callback server is working

D. 配置 Crawlbase Crawler 使用您的回调 URL

现在我们已经建立了一个工作的回调服务器并成功设计了一个数据库,现在是时候创建一个 Crawler 并将我们的回调 URL 集成到 Crawlbase 中。

登录您的 Crawlbase 帐户并导航至 创建 Crawler 页面。输入您想要 Crawler 命名并粘贴我们之前创建的回调 URL。

创建 Crawler

请注意: Crawlbase 已分配正常请求 (TCP) Crawler 对于 LinkedIn,所以我们必须选择该选项。即使选择了正常请求,值得注意的是,Crawlbase 采用了先进的 AI 机器人,其算法旨在模仿人类行为。此外,还使用了高级住宅代理来进一步提高每次抓取的成功率。

E. 运行处理器

在同一目录中打开新的控制台或终端并激活。

1
PROJECT_FOLDER$ 。 .venv/bin/激活

启动脚本 process.py

1
PROJECT_FOLDER$ python process.py

该脚本应在后台持续运行,因为它会频繁检查来自 Crawlbase 的数据 Crawler.

F. 开始爬行

在触发您的请求之前,请确保您已为脚本设置了所有正确的变量。 从以下位置获取您的正常请求/ TCP 令牌 Crawbase 帐户页面.

转到项目的主目录,打开 PROJECT_FOLDER/settings.yml 文件并添加您的 TCP 令牌值和 Crawler 名称。

1
2
令牌: < >
搜寻器: 领英-Crawler

在同一目录中打开新的控制台或终端并激活。

1
PROJECT_FOLDER$ 。 .venv/bin/激活

启动脚本 crawl.py

1
PROJECT_FOLDER$ pythoncrawl.py

发送请求后,您应该注意到您的 crawl_requests 数据库将填充正在爬网的 URL、Crawlbase 中的 RID 以及相应的状态,如下面的屏幕截图所示。

抓取请求

第四部分: Crawler 监控

爬行基地 Crawler 是一个多功能系统,提供有用的功能,包括实时监控,可以方便地实时跟踪我们自定义爬虫的请求状态。要访问该页面,只需从您的 Crawler 仪表板并点击 实时监控 标签。

Crawler 现场监控

术语的定义

爬行 - 成功抓取的总数

失败 - 内部抓取失败次数(免费)

并发抓取 - 在任何给定时间同时抓取的请求数。

等候 - 当前在队列中等待抓取的请求。

要重试的设置 - 需要重试的请求数。 Crawler 将尝试抓取目标 URL,最多重试 110 次或直到获得成功响应。

一旦 Crawler 成功完成抓取后,它会将数据传回您的回调服务器。因此,始终保持服务器的可用性至关重要。一旦收到抓取的数据,您的 linkedin_profiles 和 linkedin_profile_experiences 数据库表就会自动更新,无需人工干预。

第五部分:结论

这是一个简单的组件流程图,总结了我们的项目范围:

组件流程图

总而言之,本指南带您构建高效且高度可扩展的 LinkedIn 个人资料 Crawler 使用 Crawlbase。面对从 LinkedIn 抓取数据的挑战,本指南提供了获取有价值的专业资料信息的战略解决方案。

Crawlbase 是网络抓取领域的先驱,配备了专为 LinkedIn 数据设计的专门算法,可确保流畅的抓取体验。 该项目旨在创建一个 Flask 回调服务器,能够高效地异步捕获 LinkedIn 个人资料,并将其存储在 MySQL 数据库中。 值得注意的是,我们仅根据 LinkedIn 的条款使用公开数据。

从环境设置和脚本编写到代码执行,本指南涵盖了每个关键步骤。您将通过测试服务器、配置 Crawlbase 无缝地进步 Crawler,并启动数据请求。

Crawler 监控功能可在您前进的过程中提供实时洞察,从而增强对流程的控制。有了本指南,您就可以利用 Crawlbase 的强大功能,制作动态 LinkedIn 个人资料 Crawler 它为您的项目提供宝贵的 LinkedIn 见解。

最后,前往 GitHub上 如果您想获取该项目的完整代码库。

第六部分:常见问题

问:如何向异步请求发送附加数据并在回调服务器中检索它?

你可以通过 callback_headers 您的请求的参数。 例如,假设我们想要附加附加数据,例如 BATCH-IDCUSTOMER-ID 对于每个请求:

1
2
3
4
批次 ID = '批次 ID'
客户 ID = 'a-客户-id'
raw_callback_headers = f'批次 ID:{令牌_id}|客户 ID:{客户ID}'
编码的回调头= urllib.parse.quote(raw_callback_headers,安全='')

然后添加 encoded_callback_headers 到请求中的 url 参数。

示例:

1
爬行库_api_url = f'https://api.crawlbase.com?token=mynormaltoken&callback=true&crawler=LinkedIn-Crawler&url=https%3A%2F%2Fwww.linkedin.com%2Fin%2Fwilliamhgates%2F&autoparse=true&callback_headers={encoded_callback_headers}'

您可以通过 HTTP 请求标头在我们的回调服务器中检索这些值。 所以在我们的例子中, BATCH-IDCUSTOMER-ID 将被检索为:

1
2
batch_id = request.headers.get('批次 ID')
customer_id = request.headers.get('客户ID')

欲了解更多信息,请访问本部分 爬网文档.

问:如何保护我的 Webhook?

您还可以 保护 webhook 端点 使用以下方法的任意组合:

  • 将自定义标头附加到您的请求,其中包含一个令牌,您将验证该标头是否存在于 Webhook 中。
  • 在 URL 中使用 URL 参数,在 Webhook 请求期间检查其是否存在。 例如:yourdomain.com/2340JOiow43djoqe21rjosi?token=1234。
  • 限制仅接受 POST 请求。
  • 验证特定的预期标头是否存在,例如 Pc-Status, Original-Status, rid等等。

顺便说一句,我们建议不要将 IP 白名单列入,因为我们的爬虫可能来自各种 IP,并且这些 IP 可能会发生变化,恕不另行通知。

与抓取 LinkedIn 数据一样,网络抓取的合法性很复杂。 在里面 hiQ Labs 诉 LinkedIn Corp. 案,第九巡回法院裁定抓取公开数据可能不会违反《计算机欺诈和滥用法》(CFAA)。 然而,这是特定于 CFAA 的管辖权和解释的。 网络抓取的合法性取决于数据性质、使用的方法、协议和管辖法律等因素。

抓取受版权保护的内容或无视使用条款可能会导致法律问题。 这就是为什么 Crawlbase 只允许抓取公开可用的数据——无需登录会话即可访问的数据。

如果您需要更多地了解这如何适用于您的情况,建议您向法律专业人士寻求建议以获得准确的指导。

问:我还可以从 Crawlbase LinkedIn scraper 获取哪些其他类型的用户数据?

从 LinkedIn 个人资料中抓取的最有价值和最常见的数据如下:

  1. 姓名:用户的全名。
  2. 标题/专业:用户专业角色或专业知识的简短描述。
  3. 连接数:用户在 LinkedIn 上拥有的连接数。
  4. 位置:用户的地理位置。
  5. 封面图像:显示在用户个人资料顶部的可选横幅图像。
  6. 个人资料图片:用户的个人资料图片。
  7. 个人资料 URL:用户 LinkedIn 个人资料的唯一网址。
  8. 职位信息:有关用户当前和过去工作职位的详细信息。
  9. 教育信息:有关用户教育背景的信息。
  10. 经验:用户工作经验和职业经历的全面概述。
  11. 活动:LinkedIn 上用户生成的帖子、文章和其他活动。
  12. 资格:用户已获得的其他认证或资格。
  13. 组织:有关与用户关联的组织的详细信息。

问:为什么使用 Flask 进行 webhook?

  1. 定制: Flask 是一个 Python Web 框架,允许您创建高度可定制的 Webhook 端点。 您可以根据您的具体需求定义行为、身份验证和处理逻辑。
  2. 灵活性: Flask 为您提供了处理各种类型传入数据的灵活性,例如 JSON、表单数据或文件。 这在处理不同类型的 Webhook 负载时非常重要。
  3. 集成化: Flask 回调服务器可以轻松地与您现有的基于 Python 的应用程序或服务集成。 这使得将 Webhook 数据合并到您的工作流程中变得很方便。
  4. 身份验证和安全: 您可以在 Flask webhook 服务器中实施身份验证机制和安全措施,以确保只有授权源才能触发服务器。
  5. 调试和日志记录: Flask 提供了用于调试和日志记录的工具,这在监视 Webhook 服务器的行为和诊断任何问题时非常有用。
  6. 扩展和部署: Flask 应用程序可以部署到各种托管环境,允许您根据需要扩展 Webhook 服务器。
  7. 社区和资源: Flask 拥有一个庞大且活跃的社区,这意味着您可以轻松找到教程、文档和第三方包来帮助您构建和维护 Webhook 服务器。

问:为什么要进行更复杂的异步抓取而不是同步抓取?

同步抓取以顺序方式处理任务,这可能更简单但速度更慢,尤其是在涉及等待时。 异步爬网同时处理任务,从而提高性能和资源利用率。 它也非常适合同时处理大量任务。

实现更加复杂,调试也更具挑战性,但在这种情况下,利大于弊。 这就是 Crawlbase 推动 LinkedIn 异步抓取的原因。