细拆Python爬虫代码,建设自己的GPT助手!

GPT时代-数据的重要性

GPT是一种自然语言处理(NLP)算法,它通过处理和分析大量文本数据来自动生成具有连贯性和逻辑性的文本。此过程中用到的这些数据,也就是上下文数据:上下文数据对于GPT的训练至关重要,它们之间的关系就如同教师与学生的关系–上下文数据(教师)通过指导GPT(学生)如何理解和生成语言。

对于GPT来说,它的表现直接取决于其所训练的数据。如果数据质量高、覆盖面广、多样性强,训练出来的GPT产生的文本质量将更高,更能理解复杂的语言模式和前后文关系,更能生成符合预期的自然语言。

在我们日常的使用中,经常会遇到这样一种场景,那就是想获取某一个网页,或者网页关联的信息内容。当有了GPT之后,我们可以利用GPT快速归纳总结出这些网页的内容,从而加快自己的工作和学习效率,那么问题来了:我们怎么才能快速地获取网页上的数据?

下面我将介绍一个很棒的git仓库,只用不到100行代码就可以完成!

开始

我们直接给出项目的主体代码:

import asyncio
from playwright.async_api import async_playwright
import json
import fnmatch
from config import Config


# Function to get page HTML
async def get_page_html(page, selector):
    await page.wait_for_selector(selector)
    element = await page.query_selector(selector)
    return await element.inner_text() if element else ""


# Crawl function
async def crawl(config):
    results = []
    queue = [config.url]

    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        page = await browser.new_page()

        if config.cookie:
            await page.context.add_cookies([{
                "name": config.cookie['name'], 
                "value": config.cookie['value'], "url": config.url}])

        try:
            while queue and len(results) < config.max_pages_to_crawl:
                url = queue.pop(0)
                print(f"Crawler: Crawling {url}")
                await page.goto(url)
                html = await get_page_html(page, config.selector)
                results.append({'url': url, 'html': html})
                with open(config.output_file_name, 'w') as f:
                    json.dump(results, f, indent=2)

                # Extract and enqueue links
                links = await page.query_selector_all("a")
                for link in links:
                    href = await link.get_attribute("href")
                    if href and fnmatch.fnmatch(href, config.match):
                        queue.append(href)

                # Implement on_visit_page logic if needed
        finally:
            await browser.close()

    return results


# Main function
async def main(config):
    results = await crawl(config)
    with open(config.output_file_name, 'w') as f:
        json.dump(results, f, indent=2)


# Running the main function
if __name__ == "__main__":
    config = Config(
        url="https://www.laplace-ai.com/vision",
        match="https://www.laplace-ai.com/intro/vision/**",
        selector="#SITE_PAGES",
        max_pages_to_crawl=10,
        output_file_name="output.json"
    )
    asyncio.run(main(config))

简单解释一下,这段代码是一个基于Python协程库(asyncio)和Playwright库实现的网络爬虫,其主要功能是爬取网页内容,并将结果储存为JSON文件。大致工作流程是根据预设的URL进行网页访问,通过特定的选择器抓取相应HTML元素,获取所需数据, 并在条件下提取此页面的相关链接进行后续的爬取。

接下来,我们将步骤详细拆解:

  1. 设置配置类 Config: 在代码最末尾,有一个Config类的实例化,这是用来提供爬虫运行必要参数的具体实例。包括初始的URL、URL的匹配模式、页面的CSS选择器,爬取页面的最大数量,和输出的文件名。
  2. 主函数 main() :主要步骤是运行爬取任务并将结果写入JSON文件。
  3. 爬取函数 crawl() :这是网络爬虫的核心,它首先启动一个Chromium浏览器进行页面访问,接着对网页进行解析,抽取所需文本数据,获取新的爬取链接,并将浏览器关闭以防止内存泄漏。
    • 在这个函数中,我们首先创建了一个队列并将初始URL放入其中。然后,启动一个浏览器并打开一个新页面。
    • 如果配置中包含cookie,我们将为页面上下文添加cookie。
    • 在确保结果数小于最大爬取页数的前提下,我们会从队列中取出一个URL,前往该页面,并获取选定的元素的HTML。
    • 提取页面上的所有链接并将匹配的链接添加到队列中。
  1. 辅助函数 get_page_html() :这个函数用来抽取指定元素的HTML内容。它等待一个页面元素的渲染成功,然后获取元素的innerText。

在以上步骤中,Python的异步编程确保了高效性能,而Playwright库则提供了方便操作的页面访问和数据提取方法。

async with async_playwright() as p:
    browser = await p.chromium.launch(headless=True)
    page = await browser.new_page()

if config.cookie:
    await page.context.add_cookies([{
        "name": config.cookie['name'], 
        "value": config.cookie['value'], "url": config.url}])

await page.goto(url)
html = await get_page_html(page, config.selector)

以上四行代码是指实例化Chromium浏览器->打开浏览器新页面->如果有cookie则添加->访问url,获取页面html元素。

links = await page.query_selector_all("a")
for link in links:
    href = await link.get_attribute("href")
    if href and fnmatch.fnmatch(href, config.match):
        queue.append(href)

以上代码是对该网页所有链接进行抽取并与配置的模式进行匹配,如果满足,则将新的链接添加到队列中。

当获取到具体的内容之后,我们可以将下载下来的文本内容上传至GPT,或者国产的Coze软件,从而让GPT结合网页上下文进行更加精准的回答。

TODO

以上其实只是实现了一个基本的网络爬虫脚本,对于日常的使用应该是没问题了。但是有兴趣的同学还可以进行拓展,包括但不限于:

  1. URL过滤器:我们可以实现一个函数,用来判断某个URL是否需要过滤。这个函数可以接收一个URL作为输入,并返回一个布尔值,表示此URL是否需要被过滤。然后在把URL添加到队列之前,先调用这个过滤函数。
  2. 并发爬取:在现有的基础上,我们可以利用Python的异步特性,实现并发爬取以提高爬虫的效率。我们可以使用一个异步的任务队列来管理所有的爬取任务,并使用多个Coroutine同时处理这些任务。
  3. 增加异常错误处理:网络爬取过程中可能会出现各种意外的情况,比如网络错误、页面不存在或者被封禁等。我们应该为这些可能的问题设计好异常处理的流程,比如重试、跳过或者记录错误等。
  4. 保存HTML:目前的代码中,输出的HTML是经过处理后的文本。如果你需要更多的信息(比如,原始的HTML),可以改变爬取函数来保存整个HTML。

源代码:https://github.com/A-baoYang/gpt-crawler-py

如果上面的内容对你有帮助,请点赞收藏哦,我会分享更多的经验~

你可能感兴趣的:(AI,跃升之路,python,爬虫,gpt,人工智能)