ruanyf / weekly

科技爱好者周刊,每周五发布
45.21k stars 2.77k forks source link

【开源自荐】x-crawl 一个灵活的 Node.js AI 辅助爬虫库,使爬虫工作变得更加高效、智能和便捷 #4281

Open coder-hxl opened 5 months ago

coder-hxl commented 5 months ago

x-crawl

x-crawl 是一个灵活的 Node.js AI 辅助爬虫库。灵活的使用方式和强大的 AI 辅助功能,使爬虫工作变得更加高效、智能和便捷。

它由两部分组成:

如果您觉得 x-crawl 对您有所帮助,或者您喜欢 x-crawl ,可以在 GitHub 上给 x-crawl 存储库 点个 star 。您的支持是我们持续改进的动力!感谢您的支持!

特征

AI 辅助爬虫

随着网络技术的日新月异,网站更新变得愈发频繁,而类名或结构的改变往往给依赖这些元素的爬虫带来不小的挑战。在这样的背景下,结合 AI 技术的爬虫成为了应对这一挑战的有力武器。

首先,网站更新后类名或结构的改变可能导致传统的爬虫抓取策略失效。这是因为爬虫通常依赖于固定的类名或结构来定位并提取所需信息。一旦这些元素发生变化,爬虫就可能无法准确找到所需数据,从而影响数据抓取的效果和准确性。

然而,结合 AI 技术的爬虫则能够更好地应对这种变化。AI 还可以通过自然语言处理等技术,理解并解析网页的语义信息,从而更准确地提取所需数据。

综上所述,结合 AI 技术的爬虫能够更好地应对网站更新后类名或结构改变的问题。

x-crawl 加入 AI 辅助特性介绍

1. 智能按需分析元素 传统的爬虫工作往往需要手动分析 HTML 页面结构,提取所需的元素属性或值。而现在,借助 x-crawl 的 AI 辅助,您可以轻松实现智能按需分析元素。只需告诉 AI 您想获取哪些元素的信息,AI 便会自动分析页面结构,提取出相应的元素属性或值。

2. 智能生成元素选择器 选择器是爬虫工作中不可或缺的一部分,它能够帮助我们快速定位到页面中的特定元素。现在,x-crawl 的 AI 辅助可以为您智能生成元素选择器。只需将 HTML 代码输入到 AI 中,AI 便会根据页面结构自动为您生成合适的选择器,大大简化了确定选择器的繁琐过程。

3. 智能回复爬虫问题 在爬虫工作中,我们难免会遇到各种问题和挑战。而 x-crawl 的 AI 辅助可以为您提供智能的解答和建议。无论是关于爬虫策略、反爬虫技巧还是数据处理等方面的问题,您都可以向AI提问,AI会根据其强大的学习和推理能力,为您提供专业的解答和建议,帮助您更好地完成爬虫任务。

示例

示例1

爬虫和 AI 结合,让爬虫和 AI 获取高评分度假屋的房屋图片

import { createCrawl, createCrawlOpenAI } from 'x-crawl'

// 创建爬虫应用
const crawlApp = createCrawl()

// 创建 AI 应用
const crawlOpenAIApp = createCrawlOpenAI({
  clientOptions: { apiKey: process.env['OPENAI_API_KEY'] },
  defaultModel: { chatModel: 'gpt-4-turbo-preview' }
})

// crawlPage 用于爬取页面
crawlApp.crawlPage('https://www.airbnb.cn/s/select_homes').then(async (res) => {
  const { page, browser } = res.data

  // 等待元素出现在页面中, 并获取 HTML
  const targetSelector = '[data-tracking-id="TOP_REVIEWED_LISTINGS"]'
  await page.waitForSelector(targetSelector)
  const highlyHTML = await page.$eval(targetSelector, (el) => el.innerHTML)

  // 让 AI 获取图片链接, 并去重 (描述越详细越好)
  const srcResult = await crawlOpenAIApp.parseElements(
    highlyHTML,
    '获取图片链接, 不要source里面的, 并去重'
  )

  browser.close()

  // crawlFile 用于爬取文件资源
  crawlApp.crawlFile({
    targets: srcResult.elements.map((item) => item.src),
    storeDirs: './upload'
  })
})

过程:

查看 AI 需要处理的 HTML :由于内容太多此处放不下,就只能放在此链接 示例1 底部的 查看 AI 需要处理的 HTML

查看 AI 返回的 srcResult (房屋图片链接) ```json { "elements": [ { "src": "https://z1.muscache.cn/im/pictures/miso/Hosting-45937791/original/c67d32ed-21eb-4066-8cef-650dcd45bada.jpeg?im_w=720" }, { "src": "https://z1.muscache.cn/im/pictures/df3493cf-39b2-46cc-9e85-7ef186980f25.jpg?im_w=720" }, { "src": "https://z1.muscache.cn/im/pictures/52d375d3-5e54-444b-8186-15e61a592d9a.jpg?im_w=720" }, { "src": "https://z1.muscache.cn/im/pictures/4ce87a7c-cbce-4e6e-97ea-38840518e1c4.jpg?im_w=720" }, { "src": "https://z1.muscache.cn/im/pictures/miso/Hosting-661881998531696630/original/c7f7769f-e56c-4d55-8e74-06fdaf3e048d.jpeg?im_w=720" }, { "src": "https://z1.muscache.cn/im/pictures/miso/Hosting-50620715/original/650ba8af-3f77-41ce-8c93-0cf502a8656d.jpeg?im_w=720" }, { "src": "https://z1.muscache.cn/im/pictures/b899a44f-e5dd-4ee8-9116-13a5c79fb3d6.jpg?im_w=720" }, { "src": "https://z1.muscache.cn/im/pictures/a2820abe-20bc-4898-a0ee-17f3c974158b.jpg?im_w=720" }, { "src": "https://z1.muscache.cn/im/pictures/1f55a7c1-021f-4eb5-8e35-6473e16d7fef.jpg?im_w=720" }, { "src": "https://z1.muscache.cn/im/pictures/5205dac7-dd2a-4f91-8027-a4c0e52b4fae.jpg?im_w=720" }, { "src": "https://z1.muscache.cn/im/pictures/miso/Hosting-792178978933830608/original/75a7613c-e435-45fb-9db4-e4163921254b.jpeg?im_w=720" }, { "src": "https://z1.muscache.cn/im/pictures/bafaacfa-1644-4a3b-9165-bcd831924cc6.jpg?im_w=720" } ], "type": "multiple" } ```

示例2

爬虫和 AI 结合,让爬虫和 AI 获取豆瓣电影排行榜的电影信息

import { createCrawl, createCrawlOpenAI } from 'x-crawl'

// 创建爬虫应用
const crawlApp = createCrawl()

// 创建 AI 应用
const crawlOpenAIApp = createCrawlOpenAI({
  clientOptions: { apiKey: process.env['OPENAI_API_KEY'] },
  defaultModel: { chatModel: 'gpt-4-turbo-preview' }
})

// crawlPage 用于爬取页面
crawlApp.crawlPage('https://movie.douban.com/chart').then(async (res) => {
  const { page, browser } = res.data

  // 等待元素出现在页面中, 并获取 HTML
  await page.waitForSelector('#wrapper #content .article')
  const targetHTML = await page.$eval(
    '#wrapper #content .article',
    (e) => e.outerHTML
  )

  browser.close()

  // 让 AI 获取电影信息 (描述越详细越好)
  const filmResult = await crawlOpenAIApp.parseElements(
    targetHTML,
    `这是电影列表, 需要获取电影名(name), 封面链接(picture), 简介(info), 评分(score), 评论人数(commentsNumber)。
    使用括号的单词作为属性名`
  )

  console.log(filmResult)
})

查看 AI 需要处理的 HTML :由于内容太多此处放不下,就只能放在此链接 示例2 底部的 查看 AI 需要处理的 HTML

查看 AI 返回的 filmResult (电影的信息) ```json { "elements": [ { "name": "老狐狸", "picture": "https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2900908599.webp", "info": "2023-10-27(东京国际电影节) / 2023-11-24(中国台湾) / 白润音 / 刘冠廷 / 陈慕义 / 刘奕儿 / 门胁麦 / 黄健玮 / 温升豪 / 班铁翔 / 杨丽音 / 傅孟柏 / 高英轩 / 庄益增 / 张再兴 / 许博维 / 管罄 / 钟瑶 / 游珈瑄 / 郑旸恩 / 戴雅芝 / 姜仁 / 萧鸿文...", "score": "8.1", "commentsNumber": "29211人评价" }, { "name": "机器人之梦", "picture": "https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2899644068.webp", "info": "2023-05-20(戛纳电影节) / 2023-12-06(西班牙) / 2024(中国大陆) / 伊万·拉班达 / 阿尔伯特·特里佛·塞加拉 / 拉法·卡尔沃 / 何塞·加西亚·托斯 / 何塞·路易斯·梅地亚维拉 / 加西埃拉·莫利娜 / 埃斯特·索兰斯 / 西班牙 / 法国 / 巴勃罗·贝格尔...", "score": "9.1", "commentsNumber": "64650人评价" }, { "name": "白日之下", "picture": "https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2904961420.webp", "info": "2023-06-11(上海国际电影节) / 2023-11-02(中国香港) / 2024-04-12(中国大陆) / 姜大卫 / 余香凝 / 林保怡 / 梁仲恒 / 陈湛文 / 周汉宁 / 梁雍婷 / 龚慈恩 / 宝珮如 / 朱柏谦 / 朱栢康 / 许月湘 / 胡枫 / 鲍起静 / 高翰文 / 彭杏英 / 罗浩铭 / 谭玉瑛...", "score": "8.0", "commentsNumber": "36540人评价" }, { "name": "可怜的东西", "picture": "https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2897662939.webp", "info": "2023-09-01(威尼斯电影节) / 2023-12-08(美国) / 艾玛·斯通 / 马克·鲁弗洛 / 威廉·达福 / 拉米·尤素夫 / 克里斯托弗·阿波特 / 苏西·本巴 / 杰洛德·卡尔迈克 / 凯瑟琳·亨特 / 薇琪·佩珀代因 / 玛格丽特·库里 / 汉娜·许古拉 / 杰克·巴顿...", "score": "7.0", "commentsNumber": "130113人评价" }, { "name": "完美的日子", "picture": "https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2898894527.webp", "info": "2023-05-25(戛纳电影节) / 2023-12-21(德国) / 2023-12-22(日本) / 役所广司 / 柄本时生 / 中野有纱 / 山田葵 / 麻生祐未 / 石川小百合 / 三浦友和 / 田中泯 / 大下浩人 / 犬山犬子 / 牧口元美 / 长井短 / 研直子 / 茂吕师冈 / 县森鱼 / 片桐入 / 芹泽兴人...", "score": "8.3", "commentsNumber": "33562人评价" }, { "name": "新威龙杀阵", "picture": "https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2905374090.webp", "info": "2024-03-08(西南偏南电影节) / 2024-03-21(美国网络) / 杰克·吉伦哈尔 / 康纳·麦格雷戈 / 杰西卡·威廉姆斯 / 比利·马格努森 / 丹妮拉·曼希沃 / 吉米索拉·艾库美罗 / 卢卡斯·盖奇 / 特拉维斯·范·文克 / 达伦·巴内特 / 乔昆姆·德·阿尔梅达...", "score": "6.3", "commentsNumber": "9980人评价" }, { "name": "首尔之春", "picture": "https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2905204009.webp", "info": "2023-11-22(韩国) / 黄政民 / 郑雨盛 / 李星民 / 朴解浚 / 金成畇 / 朴勋 / 安世镐 / 郑允荷 / 丁海寅 / 南允皓 / 全秀芝 / 韩国 / 金成洙 / 141分钟 / 首尔之春 / 剧情 / 金成洙 Sung-su Kim / 韩语", "score": "8.8", "commentsNumber": "171858人评价" }, { "name": "金手指", "picture": "https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2901830629.webp", "info": "2023-12-30(中国大陆) / 梁朝伟 / 刘德华 / 蔡卓妍 / 任达华 / 方中信 / 陈家乐 / 白只 / 姜皓文 / 太保 / 钱嘉乐 / 袁咏仪 / 周家怡 / 岑珈其 / 李靖筠 / 吴肇轩 / 柯炜林 / 冯泳贤 / 杜曜宇 / 李建城 / 古永锋 / 中国香港 / 中国大陆 / 庄文强...", "score": "6.1", "commentsNumber": "135956人评价" }, { "name": "美国小说", "picture": "https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2902166424.webp", "info": "2023-09-08(多伦多国际电影节) / 2023-12-15(美国) / 杰弗里·怀特 / 翠西·艾利斯·罗斯 / 约翰·奥提兹 / 伊萨·雷 / 斯特林·K·布朗 / 埃里卡·亚历山大 / 莱斯利·格塞斯 / 亚当·布罗迪 / 凯斯·大卫 / 迈拉·卢克利希亚·泰勒 / 雷蒙德·安东尼·托马斯...", "score": "7.7", "commentsNumber": "26223人评价" }, { "name": "利益区域", "picture": "https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2899514583.webp", "info": "2023-05-19(戛纳电影节) / 2023-12-15(美国) / 克里斯蒂安·富里道尔 / 桑德拉·惠勒 / 约翰·卡特豪斯 / 拉尔夫·赫尔福特 / 弗雷娅·克罗伊茨卡姆 / 马克斯·贝克 / 伊摩根·蔻格 / 斯蒂芬妮·佩特罗维茨 / 拉尔夫·齐尔曼 / 玛丽·罗莎·提特言...", "score": "7.4", "commentsNumber": "24875人评价" } ], "type": "multiple" } ```

甚至可以将整个 HTML 传给 AI 帮我们操作,由于网站内容更加复杂你还需要更准确描述要取的位置,并且会消耗大量的 Tokens 。

即使网站后续的更新导致类名或结构发生改变也能正常爬到数据,因为我们可以不再依赖于固定的类名或结构来定位并提取所需信息,而是让 AI 理解并解析网页的语义信息,从而更高效、智能和便捷提取所需数据。

coder-hxl commented 5 months ago

目前新版 x-crawl 的 AI 辅助功能是依靠 OpenAI ,后续还可能加入其他 AI 。

coder-hxl commented 5 months ago

AI 智能按需分析元素

无需手动分析 HTML 页面结构再提取所需的元素属性或值。现在只需将 HTML 代码输入到 AI 中,并告知 AI 您想获取哪些元素的信息,AI便会自动分析页面结构,提取出相应的元素属性或值。

import { createCrawlOpenAI } from 'x-crawl'

const crawlOpenAIApp = createCrawlOpenAI({
  clientOptions: { apiKey: '你的 API Key' }
})

const HTMLContent = `
  <div class="scroll-list">
    <div class="list-item">女装带帽卫衣</div>
    <div class="list-item">男装卫衣</div>
    <div class="list-item">女装卫衣</div>
    <div class="list-item">男装带帽卫衣</div>
  </div>
  <div class="scroll-list">
    <div class="list-item">男装纯棉短袖</div>
    <div class="list-item">男装纯棉短袖</div>
    <div class="list-item">女装纯棉短袖</div>
    <div class="list-item">男装冰丝短袖</div>
    <div class="list-item">男装圆领短袖</div>
  </div>
`

crawlOpenAIApp.parseElements(HTMLContent, '获取男装, 并去重').then((res) => {
  console.log(res)
  /*
    res:
    {
      elements: [
        { class: 'list-item', text: '男装卫衣' },
        { class: 'list-item', text: '男装带帽卫衣' },
        { class: 'list-item', text: '男装纯棉短袖' },
        { class: 'list-item', text: '男装冰丝短袖' },
        { class: 'list-item', text: '男装圆领短袖' }
      ],
      type: 'multiple'
    }
  */
})

AI 智能生成元素选择器

能够帮助我们快速定位到页面中的特定元素。只需将 HTML 代码输入到 AI 中,并告知 AI 您想获取哪些元素的选择器,AI 便会根据页面结构自动为您生成合适的选择器,大大简化了确定选择器的繁琐过程。

示例:

import { createCrawlOpenAI } from 'x-crawl'

const crawlOpenAIApp = createCrawlOpenAI({
  clientOptions: { apiKey: '你的 API Key' }
})

const HTMLContent = `
  <div class="scroll-list">
    <div class="list-item">女装带帽卫衣</div>
    <div class="list-item">男装卫衣</div>
    <div class="list-item">女装卫衣</div>
    <div class="list-item">男装带帽卫衣</div>
  </div>
  <div class="scroll-list">
    <div class="list-item">男装纯棉短袖</div>
    <div class="list-item">男装纯棉短袖</div>
    <div class="list-item">女装纯棉短袖</div>
    <div class="list-item">男装冰丝短袖</div>
    <div class="list-item">男装圆领短袖</div>
  </div>
`

crawlOpenAIApp.getElementSelectors(HTMLContent, '获取所有女装').then((res) => {
  console.log(res)
  /*
    res:
    {
      selectors: '.scroll-list:nth-child(1) .list-item:nth-of-type(1), .scroll-list:nth-child(1) .list-item:nth-of-type(3), .scroll-list:nth-child(2) .list-item:nth-of-type(3)',
      type: 'single'
    }
  */
})

AI 智能回复爬虫问题

可以为您提供智能的解答和建议。无论是关于爬虫策略、反爬虫技巧还是数据处理等方面的问题,您都可以向AI提问,AI会根据其强大的学习和推理能力,为您提供专业的解答和建议,帮助您更好地完成爬虫任务。

import { createCrawlOpenAI } from 'x-crawl'

const crawlOpenAIApp = createCrawlOpenAI({
  clientOptions: { apiKey: '你的 API Key' }
})

crawlOpenAIApp.help('x-crawl 是什么').then((res) => {
  console.log(res)
  /*
    res:
    x-crawl 是一个灵活的 Node.js AI 辅助爬虫库,它提供了强大的人工智能辅助功能,可以帮助开发者更高效、智能和便捷地进行网络爬虫工作。您可以在 GitHub 上找到更多关于 x-crawl 的详细信息和使用方式:https://github.com/coder-hxl/x-crawl。
  */
})

crawlOpenAIApp.help('爬虫的三大注意事项').then((res) => {
  console.log(res)
  /*
    res:
    在进行爬虫工作时,有三个重要的注意事项需要特别注意:

    1. **遵守网站规则和法律法规**:在进行数据爬取时,一定要遵守网站的robots.txt文件中的规则,并且不要违反任何相关的法律法规。尊重网站所有者的意愿和数据的所有权是非常重要的。

    2. **避免对网站造成过大负担**:爬虫在爬取数据时会占用网站的带宽和资源,过度频繁的访问会给网站带来压力甚至是瘫痪。因此,需要合理设置爬虫的访问频率,并且避免对网站造成过大的访问负担。

    3. **数据处理和存储的合法性和隐私保护**:爬取到的数据可能涉及用户的隐私信息,因此在收集、存储和使用这些数据时,要符合相关的隐私保护法律法规,并且不要滥用这些数据。另外,在处理数据时也要保证数据的准确性和可靠性,避免因不当的数据处理而产生误解或造成不良影响。
  */
})

你甚至可以将整个 HTML 传给 AI 帮我们操作,由于网站内容更加复杂你还需要更准确描述要取的位置,并且会消耗大量的 Tokens 。