一日一技:写XPath也并不总是这么简单
初级爬虫工程师有时候又叫做XPath编写员,他们的工作非常简单也非常繁琐,就是拿到网页的HTML以后,写XPath。并且他们觉得使用模拟浏览器可以解决一切爬虫问题。
很多人都看不起这个工作,觉得写XPath没有任何技术含量,随便找个实习生就能做。这种看法大部分情况下是正确的,但偶尔也有例外,例如今天我要讲的这个Case,可能实习生还搞不定。
初级爬虫工程师有时候又叫做XPath编写员,他们的工作非常简单也非常繁琐,就是拿到网页的HTML以后,写XPath。并且他们觉得使用模拟浏览器可以解决一切爬虫问题。
很多人都看不起这个工作,觉得写XPath没有任何技术含量,随便找个实习生就能做。这种看法大部分情况下是正确的,但偶尔也有例外,例如今天我要讲的这个Case,可能实习生还搞不定。
我们经常让大模型返回Markdown格式的文本,然后通过Python的markdown
库把文本渲染成HTML。
但不知道大家有没有发现,大模型返回的Markdown并不是标准的Markdown。特别是当返回的内容包含列表时,大模型返回的内容有问题。例如下面这段文本:
1 | **关于这个问题,我有以下看法** |
你粗看起来没有问题,但当你使用markdown
模块去把它渲染成HTML时,你会发现渲染出来的结果不符合你的预期,如下图所示:
在使用Scrapy的时候,我们可以通过在pipelines.py里面定义一些数据处理流程,让爬虫在爬到数据以后,先处理数据再储存。这本来是一个很好的功能,但容易被一些垃圾程序员拿来乱用。
当我们采购数据集时,有时候供应商会以JSON Lines的形式交付给我们。这种格式,本质上是文本格式,它每一行是一个JSON。例如,供应商给我们了一个文件小红书全量笔记.json
文件,我们可以使用如下Python代码来一行一行读取:
1 | import json |
这个格式的好处在于,每一次只需要把少量内容读取到内存中。即便这个文件有1TB,我们也可以使用一个4GB内存的电脑来处理。
今天出了一个乌龙事件,某数据供应商在给我数据的时候,说的是以JSON Lines格式给我。但我拿过来解压缩以后一看,100GB的文件,里面只有1行,如下图所示:
也就是说,他用的是一个超大JSON直接导出给我,并没有使用JSON Lines格式。正常情况下,如果我要直接解析这个数据,需要我的电脑内存超过100GB。
这个大JSON大概格式是这样的:
1 | [{"question": "xxx111", "answer": "aaa", "crawled_time": "2025-05-01 12:13:14"}, {"question": "xxx222", "answer": "aaa", "crawled_time": "2025-05-01 12:13:14"}, {"question": "xxx333", "answer": "aaa", "crawled_time": "2025-05-01 12:13:14"}, ...] |
要解决这个问题,有三种方法。
如果这个JSON里面没有嵌套数据,只有一层key: value
。那么非常简单。一个字符,一个字符读取。遇到}
的时候,说明一条子JSON数据已经读取完成,解析以后再读取下一条子JSON。
如果这个JSON里面有嵌套结构,那么可以使用经典算法题里面的数括号算法来解决。当发现}
的数量等于{
的时候,说明一个子JSON已经读取完成,可以解析了。
今天我们来介绍第三种方法,使用一个第三方库,叫做ijson
。它天然支持解析这种超大的JSON,并且代码非常简单:
1 | import ijson |
运行效果如下图所示:
既不会占用大量内存,又能正常解析超大JSON。
今年315晚会曝光了几个获客软件,号称可以拦截任何人的网络浏览记录,并根据对方在直播软件的留言、打过的电话、浏览过的网址,获取对方的手机号和微信号。还有在地图上随便画一个圈,就能找到圈里面130万人的联系方式。
作为一个软件工程师,我来说说我对他们背后原理的猜测。
这两天我使用Cursor开发了一个新闻网站的前端+后端。在开发的过程中,我总结了一些适合于我自己的最佳实践。这些方法让我在使用Cursor的时候,几乎没有遇到任何阻碍,非常顺利,非常流畅地完成了网站的开发。
我的开发经验,总结起来一句话就能说清楚:多写文档少聊天。下面我来详细说一下具体方法。
我买的房子今天交房了。开发商配的门锁是某品牌的智能门锁,它可以使用指纹开锁,也可以使用密码开锁。在使用手机跟门锁配对以后,可以远程在手机上生成临时密码。临时密码只能使用1次,并且在生成的30分钟内有效。这个功能可以方便装修人员进出又不用担心泄露密码。
因为新房子还没有通网,所以门锁肯定是无法连接互联网的。而装修人员给我打电话要临时密码时,我在公司,离家几十公里外,门锁也不可能跟手机通信。
那么问题来了,门锁是怎么验证这个临时密码合法的?
大家肯定经常在微信公众号里面看到类似于《30秒使用Cursor开发xxx》这种文章。典型的标题党装逼货,大家当个笑话看就行了。
Cursor目前还没有强到真的让一个完全不懂代码的人轻轻松松开发一个有用的软件,但Cursor确实可以让懂代码的人如虎添翼。正好最近有不少同学在群里面问我,如何正确使用Cursor:
那么今天我就来讲讲我使用Cursor的一个场景:快速理解开源项目的核心逻辑。
以Cline为例,这是一个VSCode插件,能够让VSCode实现Cursor的功能,配合DeepSeek最新模型,有人声称可以完美平替Cursor。那么,如果我完全看懂了Cline的原理,也就相当于看懂了Cursor的实现原理了。那么我们来看看如何使用Cursor辅助我学习Cline的源代码。
使用过Dify的同学都知道,你可以在上面拖动方框和箭头来编排大模型的逻辑,如下图所示。
这种拖动框图编排工作流的方式,确实非常简单方便,以至于不会代码的人也可以用来编排大模型Agent。但你有没有考虑过一个问题——你作为一个工程师,有没有可能通过写代码的形式来编排工作流?否则你和不懂代码的人相比有什么竞争力?
经常有同学在微信群里面咨询,如何使用大模型从非结构化的信息里面提取出结构化的内容。最常见的就是从网页源代码或者长报告中提取各种字段和数据。
最直接,最常规的方法,肯定就是直接写Prompt,然后把非结构化的长文本放到Prompt里面,类似于下面这段代码:
1 | from zhipuai import ZhipuAI |