为了账号安全,请及时绑定邮箱和手机立即绑定

如何用Python和Crawlee创建一个LinkedIn职位爬虫

简介,

在这篇文章里,我们将使用Crawlee和Streamlit构建一个网络应用程序,用于从LinkedIn上抓取数据。

我们将使用Python的Crawlee库创建一个LinkedIn工作抓取器,该抓取器可以从Web应用程序中动态接收的用户输入中提取公司名称、职位标题、发布时间和工作发布链接。

注意
我们的一位社区成员写了一篇博客投稿到Crawlee Blog。如果您也有类似的文章想要投稿,可以通过我们的discord频道与我们联系。

完成本教程时,您将能够使用一个功能完整的网络应用从LinkedIn上收集工作招聘信息。

领英职位抓取器
点击图片查看领英职位抓取器

咱们开始啦。

此处省略

先决条件

让我们开始通过运行以下命令来创建一个新的Crawlee for Python项目:

# 如下所示
运行pipx来运行crawlee并创建一个名为linkedin-scraper的项目

全屏模式 退出全屏

当 Crawlee 在终端中要求你选择时,选择 PlaywrightCrawler

安装完成后,Crawlee for Python 会自动生成样板代码。你可以使用 cd 命令切换到项目文件夹,然后运行此命令来安装所需的依赖包。

poetry install  # 这里我们使用poetry来安装依赖包。

点这里进入全屏,点击退出全屏

我们要开始处理Crawlee提供的文件,以便能够构建我们的抓取器。

注意
如果你喜欢这篇博客,能在 GitHub 上给 Crawlee for Python 点个赞就太好了。

给我们的项目点个赞吧 ⭐️

用Python和Crawlee构建LinkedIn工作爬虫

在这节,我们将使用Python版的Crawlee包来构建爬虫程序。想了解更多关于Crawlee的信息,请参阅他们的文档

1. 查看领英的工作岗位搜索页面

在您的网络浏览器里打开LinkedIn网站,然后退出网站(如果您已登录账户)。您应该看到类似这样的界面。

LinkedIn 的主页

进入工作部分,搜索你想要的工作和地点,然后复制该工作页面的网址。

LinkedIn 职位页面

你应该有这样类似的东西:

https://www.linkedin.com/jobs/search?keywords=后端开发者&location=Canada&geoId=101174742&trk=public_jobs_jobs-search-bar_search-submit&position=1&pageNum=0

我们要特别注意的是,在'? '后面的搜索参数,尤其是关键词和位置参数,对我们来说最关键。

用户提供的岗位名称将作为关键词参数输入,而用户提供的地点将作为位置参数输入。最后,我们将移除geoId参数,保持其他参数原样。

我们将对main.py文件做一些改动。将下面的代码复制粘贴到你的main.py文件中。

    from crawlee.playwright_crawler import PlaywrightCrawler
    from .routes import router                                     
    import urllib.parse

    async def main(title: str, location: str, data_name: str) -> None:
        base_url = "https://www.linkedin.com/jobs/search"

        # 对 URL 参数进行编码
        params = {
            "keywords": title,
            "location": location,
            "trk": "public_jobs_jobs-search-bar_search-submit",
            "position": "1",
            "pageNum": "0"
        }

        encoded_params = urlencode(params)

        # 将这些参数编码成查询字符串
        query_string = '?' + encoded_params

        # 将基础 URL 和已编码的查询字符串拼接起来
        encoded_url = urljoin(base_url, "") + query_string

        # 初始化爬虫实例
        crawler = PlaywrightCrawler(
            request_handler=router,
        )

        # 使用包含初始 URL 的列表运行爬虫
        await crawler.run([encoded_url])

        # 等待爬虫将数据导出到 CSV 文件中
        output_file = f"{data_name}.csv"
        await crawler.export_data(output_file)

点击这里进入全屏模式,点击这里退出全屏模式

现在我们已经对URL进行了编码,接下来我们需要调整生成的路由来处理LinkedIn上的工作帖子。

2. 为您的爬虫设置路由

我们将为你的应用使用两个处理单元:

  • 默认处理方式

default_handler处理的是初始URL

  • 找工作

job_listing处理程序提取每项工作的详细信息。

职位爬虫将爬取职位发布页面上的信息,并提取所有职位发布的链接。

看看这些元素

当你查看职位发布时,你会发现这些链接就是职位发布,位于一个名为 jobs-search__results-list 的有序列表中。我们将利用 Playwright 定位器来提取这些链接,并将它们加入到 job_listing 路由中处理。

    router = Router[PlaywrightCrawlingContext]()

    @router.default_handler
    async def default_handler(context: PlaywrightCrawlingContext) -> None:
        """默认请求处理器."""

        #select all the links for the job posting on the page
        hrefs = await context.page.locator('ul.jobs-search__results-list a').evaluate_all("links => links.map(link => link.href)")

        #add all the links to the job listing's route
        await context.add_requests(
                [Request.from_url(rec, label='job_listing') for rec in hrefs]
            )

全屏,退出全屏

现在我们已经拿到了工作列表,下一步是获取它们的详细信息吧。

我们将提取每个工作的标题、公司的名称、时间以及工作帖子链接。打开您的开发工具面板,使用 CSS 选择器来提取每个元素。

来看一下元素

在抓取后处理每个列表后,我们将清理文本中的特殊字符,并使用context.push_data函数将数据存储到本地。

    @router.handler('job_listing')
    async def listing_handler(context: PlaywrightCrawlingContext) -> None:
        """处理职位列表的函数。"""

        await context.page.wait_for_load_state('load')

        job_title = await context.page.locator('div.top-card-layout__entity-info h1.top-card-layout__title').text_content()

        company_name = await context.page.locator('span.topcard__flavor a').text_content()   

        time_of_posting = await context.page.locator('div.topcard__flavor-row span.posted-time-ago__text').text_content()

        await context.push_data(
            {
                # 我们使用正则表达式来移除提取文本中的空格和换行符

                'title': re.sub(r'[\s\n]+', '', job_title),
                '公司名称': re.sub(r'[\s\n]+', '', company_name),
                '发布时间': re.sub(r'[\s\n]+', '', time_of_posting),
                'url': context.request.loaded_url,
            }
        )

进入全屏模式。退出全屏模式。

3. 创建你的应用。

对于此项目,我们将使用Streamlit来创建网络应用。在我们继续之前,我们将在项目目录中创建一个名为app.py的新文件。此外,请确保您已经在全局Python环境中安装了Streamlit,然后再继续此部分。

    import streamlit as st
    import subprocess

    # Streamlit 表单输入
    st.title("LinkedIn 职位爬虫")

    with st.form("scraper_form"):
        title = st.text_input("职位标题", value="backend developer")
        location = st.text_input("工作地点", value="newyork")
        data_name = st.text_input("文件名", value="backend_jobs")

        submit_button = st.form_submit_button("开始爬取")

    if submit_button:

        # 使用表单输入运行爬虫脚本
        command = f"""poetry run python -m linkedin-scraper --title "{title}"  --location "{location}" --data_name "{data_name}" """

        with st.spinner("正在爬取..."):
             # 执行命令并显示结果
            result = subprocess.run(command, shell=True, capture_output=True, text=True)

            st.write("脚本结果:")
            st.text(result.stdout)

            if result.returncode == 0:
                st.success(f"数据已成功保存为 {data_name}.csv")
            else:
                st.error(f"错误信息: {result.stderr}")

切换到全屏模式 退出全屏

Streamlit网络应用接受用户的输入,并使用Python的subprocess模块来运行Crawlee抓取脚本。

4. 测试你的 app

在测试应用程序之前,我们先需要对__main__文件进行一些调整,以便它能接受命令行参数。

    import asyncio
    import argparse

    from .main import main

    def get_args():
        # ArgumentParser对象用于从LinkedIn爬取职位列表
        parser = argparse.ArgumentParser(description="从LinkedIn爬取职位列表")

        # 定义以下参数
        parser.add_argument("--title", type=str, required=True, help="职位名称(必填)")
        parser.add_argument("--location", type=str, required=True, help="职位地点(必填)")
        parser.add_argument("--data_name", type=str, required=True, help="输出CSV文件的名称(必填)")

        # 解析参数
        return parser.parse_args()

    if __name__ == '__main__':
        args = get_args()
        # 运行主函数并传递解析后的参数
        asyncio.run(main(args.title, args.location, args.data_name))

进入全屏 退出全屏

我们将在终端中运行以下代码来启动Streamlit应用程序:

在命令行中运行 `streamlit run app.py` 这个命令

全屏模式, 退出全屏

比如你这个应用在浏览器里应该看起来是这样的。

启动爬虫

你会看到一个界面,显示爬虫运行已完成。

填写输入表

要查看抓取的数据,请进入您的项目文件夹,然后打开CSV文件就可以了。

CSV 文件,包含从 LinkedIn 抓取的所有工作信息

你的 CSV 文件输出应该像这样。

结尾.

在这篇指南中,我们学习了如何使用Crawlee抓取LinkedIn上的职位信息。希望你使用Crawlee构建抓取应用时能玩得开心。

你可以在这个链接中找到完整的爬虫,在 GitHub 仓库

关注Crawlee,查看更多这样的内容。

crawlee 图片

Crawlee 关注一下(了解更多关于Crawlee的信息)

Crawlee 是一个用于网页抓取和浏览器自动化的库,可以帮助你快速地构建可靠的爬虫。

谢谢。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消