分类 未分类 下的文章
解析迈克尔·杰克逊《黑或白》MV
前半段MV毫无疑问是对抗种族主义、无论国籍肤色、期待世界大同的。然而后半段大多数人看不明白,包括我20年前第一次看的时候也没看懂。这儿结合一些资料和自己的理解,解读从黑豹出现开始的后半段。
6:34 黑豹出现。黑豹党(The Black Panthers)一度在美国被当做是恐怖组织,他们确实好战激进,然而他们在清除社区毒品和犯罪中取得了很大成就,最后却被CIA等组织打击。
6:37 黑豹向门口的乔治华盛顿雕像怒吼一声表达不满。乔治华盛顿是美国首任总统,却支持奴隶制,在自己的种植园蓄奴,还和一个女奴隶生了个娃。
6:43 黑豹走下楼梯。隐喻潜入社会表层以下,揭露和防抗其黑暗面。
7:00 忽然开启聚光灯,杰克逊开始跳踢踏舞。聚光灯隐喻舞台,踢踏舞起源于黑人,又被白人主义者当做是下贱的舞蹈,甚至在表演中白人涂成黑脸(即充满种族歧视的黑脸喜剧)跳踢踏舞、扮演丑角逗乐观众。忽然将黑人置于舞台上踢踏舞,是白人强加于黑人、以种族歧视娱乐白人自己的丑恶行径。
7:18 一只猫跳出来,杰克逊看了一眼就走开了。猫豹同类,前者温顺,后者狂野。隐喻不去做黑暗体制下温顺的猫咪,而是要做一只豹子反抗黑暗压迫。
7:26 杰克逊来到街道上要跳自己的舞蹈。这个街道显然是在下层人聚集的贫民窟。然而狂风大作,各种垃圾吹过来,还有一张报纸死死贴在脚下。隐喻反抗将要开始之时,各种黑暗的打击带着下作的消息扑面而来,还死死缠着你不放。然而杰克逊毫不动摇的眼神、以及随性、坚硬、畅快的舞蹈,寓意反抗白人的禁锢和嘲笑,表达黑人自己的反抗诉求。
8:40 白色3K党标志、希特勒不死(Hitler Lives)、纳粹万字标志、黑人滚回家去、不要外国移民(No More Wetbacks)……等等都被愤怒的杰克逊暴力打碎。3K党(Ku Klux Klan)是典型的白人至上主义,原称白人种族集会。希特勒迫害犹太种族也是种族主义的代表,可恨的是现在仍有人信奉。WetBacks(湿背人)原指的是墨西哥移民,他们从墨西哥泅渡美国,因此背上都是湿的,后来也泛指外国非法移民。
9:12 杰克逊标志性的捂裆动作伴随咆哮,这儿很明显一个特写并且手指缓慢向下滑动。然后他掏出方向盘砸了3K Rules(白人至上规则)。这一段舞蹈裆部拉链没拉上。到 9:25 才一下拉起来。特别直白地隐喻美国名句Fxxk you up(淦你老木),淦完以后拉上收工。在迈克尔去世后多年,3K党至今却仍然活跃,悲哀!淦你老木啊!我觉得第二层隐喻是下层人也有不被压抑享受性自由的权利,而不只是那些上层白人所独享的。
9:44 三次重复蒸汽喷往全身的镜头。杰克逊是一直信基督的,所以我暂且采信弹幕中说的这是三次洗礼:浸洗礼、注水礼、洒水礼。然后跪地朝拜、激起圣水、撕破衣物(有献祭的意思)、撒上灯红酒绿的“皇家徽章酒店”,招牌落地。Royal Arms应该是指Royal Coat of Arms,即皇家徽章,是英国的国徽。殖民主义和奴隶贩卖也正是英国带到北美这片土地的。这儿似乎意味着铲除了种族主义的根源,也才能平静的回归本性(黑豹)离开。
另外,漫威的《黑豹》也是以黑豹作为黑人领袖象征,应该并不是巧合。
参考文章:
https://www.innermichael.com/2011/05/05/black-or-white-part-iii-panther-dance/
https://en.wikipedia.org/wiki/Tap_dance
https://en.wikipedia.org/wiki/Wetback_(slur)
https://baike.baidu.com/item/%E5%9C%A3%E6%B4%97%E7%A4%BC%E4%BB%AA/20386854?fr=aladdin
https://baike.baidu.com/item/%E8%8B%B1%E5%9B%BD%E7%9A%87%E5%AE%B6%E5%BE%BD%E7%AB%A0/5032952?fr=aladdin
自动化代码审查工具
今天看到新闻说代码审查也可以自动化,搜索了一下确实还有不少工具。
https://wenku.baidu.com/view/8f28edd507a1b0717fd5360cba1aa81144318fa1.html
但似乎自动化代码审查只是lint吗? 我希望是AI智能一些的.
NLP自然语言处理API
情感分析
一件事情给人造成正负面情感影响, 将会促使人进行相应的行动, 因此具有预测性.
百度的API分析情感还是比较准确的.只是只能分析2048个字符, 换成汉字就只有1024个.
百度多实体情感倾向分析可以在文章中分析不同实体的情感倾向.目前邀测阶段. 可以分析娱乐/财经/体育类型, 输入包括标题和正文, 正文可达6000字节.
判断两段文本说的是「同一件事情」
某一件事情第一次出现是新闻, 第二次就不是了. 所以怎么判断第二次说的和第一次的是同一件事情?
知乎上有个问题是问这个的, 答案有这么几种:
- 语义匹配
- 语义角色标注(SRL, semantic role labelling)
百度API有短文本相似度, 最大512字节. 似乎不能判断英文和中文的相似度, 不过对中文判断似乎还好. 如"笔记本"和"膝上型电脑"相似度为0.70, 与"手提电脑"相似度为0.60, 与"手机"相似度为0.36,判断还算正确.
还有词义相似度, 最大64字节.
但对于文章相似度分析还差得很远.
另一个思路, 从文章中抽取高频关键词, 看关键词是否有一致的.
python爬虫: scrapy, splash
scrapy直接用并不好用, 对于需要js渲染或动态dom的网页, scrapy爬不到.
这时候需要splash 中文文档 英文原档, 动态解析js并返回其最终渲染结果. splash实际上是一个docker image, 需要预先安装docker,然后拉取下来就可以用. 另外splash是基于lua的, 嗯, 感觉python+docker+lua,真是个缝合怪啊
介绍文章: https://www.bilibili.com/read/cv12375274
github上有一个scrapy-splash的项目.
scrapy-splash使用方法
安装scrapy, splash, scrapy-splash
pip install scrapy
docker pull scrapinghub/splash
docker run -p 8050:8050 -p 5023:5023 scrapinghub/splash
# 在上一步命令以后,命令行界面将挂起运行docker, 此时需要新建一个命令行继续运行后面的命令
pip install scrapy-splash
新建一个scrapy项目
scrapy startproject tutorial
修改其中的settings.py文件, 简便起见, 加入下面内容即可
SPLASH_URL = 'http://127.0.0.1:8050'
DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'
FEED_EXPORT_ENCODING = 'UTF-8'
SPIDER_MIDDLEWARES = {
'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
}
DOWNLOADER_MIDDLEWARES = {
'scrapy_splash.SplashCookiesMiddleware': 723,
'scrapy_splash.SplashMiddleware': 725,
'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
}
在spiders目录下, 新建一个爬虫文件, 比如爬虫名字叫df, 文件名字叫df_spider.py
import scrapy
from scrapy_splash import SplashRequest
class MySpider(scrapy.Spider):
name = 'df'
start_urls = ["http://example.com", "http://example.com/foo"]
def start_requests(self):
for url in self.start_urls:
yield SplashRequest(url, self.parse, args={'wait': 0.5})
def parse(self, response):
page = '1' # response.url.split("/")[-2]
filename = f'df-{page}.html'
with open(filename, 'wb') as f:
f.write(response.body)
项目目录下运行爬虫,会得到一个df-1.html的文件.
scrapy crawl df
查看这个文件是不是已经有js渲染, 如果还是没有渲染, 可增加爬虫文件中splash的wait时间, 上面设置的是0.5秒.
splash click一个元素的方式:
assert(splash:runjs('document.querySelector(".next a[href]").click()'))Windows10支持多用户远程桌面的方式
正常来说是不支持的. 看了很多文章, 这一篇https://www.helpwire.app/blog/allow-multiple-remote-desktop-connections-windows-10/是讲的最好的.
里面提到了几种方式, 一种是用github项目RDP Wrapper, 我试过好像不起作用. 另一个是修改Termsrv.dll文件, 用到hex编辑器, 这个管用.
copy c:\Windows\System32\termsrv.dll termsrv.dll_backup
takeown /F c:\Windows\System32\termsrv.dll /A
icacls c:\Windows\System32\termsrv.dll /grant Administrators:F
Net stop TermService
接着在十六进制编辑器里面搜索39 81 3C 06 00 00 0F 84 XX XX XX XX, 替换为B8 00 01 00 00 89 81 38 06 00 00 90,然后运行Net start TermService或者重启就可以了
C语言宏#define中#,##,#@和\的用法与define的字符串自动拼接功能
C语言宏#define中#,##,#@和\的用法: https://blog.csdn.net/yishizuofei/article/details/81022590
define还有自动拼接字符串的功能, 如:
#define str "a" "b" // 相当于str是"ab"
#define x "+"
#define str2 "a" x "b" //相当于str2是"a+b"
void main(){
printf(str);
printf(str2);
}
//将打印出 aba+b[原创]消费级产品四要素
四种基础要素
消费级产品是四种基础要素, 简称四要素. 这四个要素是消费市场对产品认可的关键. 包括:
- 外观. 外观至少占一半购买决策因素. 一眼看上去是不是喜欢, 值不值钱, 品质如何等等.
- 功能. 功能和价格构成另一半购买决策因素. 功能也是形成产品差异化的重要因素. 所谓同质化竞争一般就是指功能同质化.
- 品质. 品质是内在属性, 在购买决策时难以被消费者迅速感知. 消费者只能间接通过外观/价格/品牌/网上评价等因素判断.品质与价格一般会呈现此消彼长的关系.
- 价格. 价格区分消费层级. 人们对自己的预算以及这个产品应该值多少钱有自己的判断, 并将预算与目标价格产品形成匹配. 市场同质化竞争激烈的时候产品变成价格战, 进而牺牲难以感知的品质要素, 市场劣币驱逐良币, 不适合创业项目进入.
杠杆要素
杠杆要素是对基础要素组合成的产品形成杠杆加倍效果的. 是让消费者快速对产品形成认知的手段.
基础要素是1, 杠杆要素是后面的0. 基础要素做的不好, 杠杆越大越会反噬产品.
- 市场. 是通过市场宣传形成消费者对产品本身或产品品牌的认知, 影响消费者决策.
- 销售. 是直接让消费者或渠道形成购买决策并产生收入.
- 生态. 构建或融入一个生态, 利用生态促进消费者决策.
规模要素
规模要素影响这款产品能形成什么样的销售规模.
- 周期. 包括市场周期, 产品开发周期和产品量产周期. 市场是瞬息万变的, 适合一个品牌的产品的市场, 都有一个时间窗口, 这就是市场周期. 开发周期越长越不能及时对市场时间窗口的变化迅速反应. 导致市场错失良机. 量产周期影响库存备货和销售,进一步影响资金占用和现金流, 量产周期过长使得一段时间内备货过多,不能对市场淡旺季和临时加单及时反应, 导致库存或者积压或者不足.
- 数量. 产品生产能达到什么样的数量, 日产能/月产能是多少.
投入一个产品的节奏
创业项目或者小微企业, 先应该选择产品赛道. 选择赛道应该评估:
- 市场周期是否在上升前期.
- 产品功能是否有差异化, 是否在自己能力范围内.
- 是否有个优秀的愿意合作的代工工厂.
- 是否能在上升期之前将产品上市.
本着最小投入最大收益, 应从最重要的要素外观和功能起开始投入, 价格方面应有充裕余量, 不应切入以相同功能切入同质化严重的价格战市场.
切入顺序:
- 有自己的软硬件的开发能力, 确保功能的差异化. 软硬件开发当然有第三方的方案公司可以提供, 然而这种方案一般已经比较成熟, 也就没有什么门槛, 容易同质化. 即使差异化的功能对方开发出来, 卖得好了要升级, 对方也很可能漫天要价. 此时ID/结构/供应链/项目管理都可以找一家优秀的代工企业完成. 只是需要注意: ID设计要按照自己的市场调研的想法进行.
- ID设计能力. ID设计在消费决策中占比大, 对于公司的持续发展, 也需要持续储备产品ID设计. 因此在公司每年有4款以上产品推出时,应有自己的自己ID设计能力。
- PMC物控和供应链管理能力。物控与供应链管理紧密结合,是确保公司利润、降低产品成本的重要手段。这里假设一个优秀的代工厂已经设计了优秀的结构和产品组装流程,下一步管控交期和成本的责任不能完全交给供应商,因为这不是他的利益所在。通过降低MOQ、交期、成本等降低公司最终成本,获得收益。
- 项目管理和结构设计能力。结构设计承上启下,一方面实现ID设计,另一方面实现量产设计。好的结构设计能降低产品各个方面的成本,包括原料价格、模具可实现性、组装难度等等。拥有这项能力,对代工厂的要求可以大大降低。
- 产线设计和品控能力。设计合理的作业指导书,对各个环节IQC、IPQC、OQC进行控制。此时工厂变成了单纯的代工角色,对产品的成本和品质有较好的控制,在产品市场成熟期也能建立品牌,进入主流价格区间,甚至有一定价格战的底牌。
我是否相信存在那么几个人,他所说所做的一切全都是对的?
人们遇到比自己更优秀的人,要么丑化他,要么神话他。我觉得这是刻在基因里面的。基因要求更优秀的人塑造更好的基因环境。
可一旦神化了一个人,这个人就没有缺点了,他大概每天要做的事情就是正确的事情,别的事情他大概都不会做了。现在可以把这么一个人代入想象一下:这个人是不是要吃饭?要不要做爱?会不会放屁拉屎尿尿?
更重要的是,这个人真的不会说错话做错事吗?想想那些现在的和过去的伟大的人物,他们有这样那样的称号:伟人、圣贤、活佛、神……互联网时代还会叫某某爸爸。当然也感谢这个时代,信息每分每秒从地球各地传来,能让我们认识到,即使是做到顶级优秀的人,他也是在不断地犯错。乔布斯会犯错,他也出过失败的产品比如Lisa。马斯克也会犯错,他回顾自己在做Roadster的时候拿着创业团队的开发手板当做量产,还买了莲花汽车的油车底盘当电车底盘,可谓是一错再错。做领导到顶级的,美国总统应该算是其一了吧,那么川普和拜登满嘴跑火车的可就更多了。
既然商界神一样的人物乔布斯马斯克会犯错,既然政界顶级的大佬也会犯错,那么不如他们的大批大批人类————或许我该说所有人类————当然也会大把大把的犯错。推而广之,历史上的所有人类概莫能外。我们之所以没看到他们犯错,大概率是因为他们自己或者他们身边的人不让我们看到。既然家丑都不得外扬,圣贤伟人之错就更不能说了。还有,在他们作为圣贤伟人的时间和地域之内看不到错误,在这之外可就大把错误了。比如当朝皇上不会有错,后世评价可就未必了。朝鲜总书记在朝鲜不会有错,在朝鲜之外可是调侃对象了。
还有孔圣人,活着的时候没当成圣人,都没有国家接纳,那时候看起来肯定很多错。汉朝董仲舒“罢黜百家,独尊儒术”之后才成了圣人,此时孔子已经死了300多年。到了20世纪初期新文化运动,孔子被鲁迅为代表的一众人骂的狗血喷头,直到十年之劫时期还要打倒孔家店。到今日,我们又在全球到处开办孔子学院,又开始尊儒术,不知孔子他老人家的问题还说不说得了。
那么,圣贤伟人为什么可以成为圣贤伟人?有时候是运气,有时候是认准了方向与自己能力匹配坚持了下去(也即是准确预测了未来并投资了未来)。皇帝太子当了皇帝,必然有运气,投胎不对基本没戏。另外商界成功运气之外还是看综合预测能力,即使我小错不断,但大方向对了,而且还有能力比别人提前实现,那就能最后成功,成功之后成了神,就“没有错误了”。
所以,不能怕犯错,关键要做决策。方向要搞对,搞对就得坚持。
城市住宅内饰装修发展方向设想
是需要解决以下矛盾:
- 物品多而杂, 收纳困难-->电器和家具功能集成化小型化
- 各人因学习需要上网课, 工作需要在线会议, 娱乐需要看各自的视频, 需要解决独享私密空间和共享公共空间之间的矛盾.
- 需要解决在家办公学习更便利却产生的紧张感, 和家庭温馨舒适环境的矛盾-->办公用品/电器/软装从冷酷变得家居化.
办公室的办公环境喜欢用黑白或者蓝色等冷色调, (暖色调限于员工办公桌面)以及大量的玻璃隔断, 老板房间喜欢用棕红色木纹, 小到只摆放一套茶具, 达到整个房间用红木装修, 体现自己和公司的气派. 所有装饰横平竖直, 几乎看不到大圆角和曲线, 展示的是一种规矩. 人接触的大多数平面为硬表面, 办公椅千篇一律, 除了老板的大皮椅子, 大多数椅子采用绒布表面, 椅垫不厚. 不柔软就缺少温暖.
所以目标是既实用又温馨.
有舍才有得, 哪些家具应该被换掉?
- 房间较小的家庭, 儿童房二层为床,一层可以作为专注力的学习空间.
- 房间较大的家庭, 已经购置学习桌或者打算购置学习桌的, 可以替换掉学习桌所占用的面积.
- 对于主卧, 也可以做成双层, 两种方案, 一是上面床下面办公, 这种方式感觉多了一层疲惫感, 每次还要爬上去; 另一种是下面床上面办公. 这种方式要一定防止大的噪音, 如脚步声和挪动桌椅的声音.
- 对于客厅,可以把沙发换成学习办公房. 学习办公的时候最好可以把电视收起来或者隐蔽起来.
蓝牙按键(蓝牙遥控器)芯片方案
从B站视频https://www.bilibili.com/video/BV1D34y1e7Yh?spm_id_from=333.337.search-card.all.click拆解两个蓝牙遥控器的方案中发现线索, 大款的遥控器采用的是Yichip 易兆微 的YC1039芯片.
从易兆微的官网上开到YC10xx系列主要用于防丢器,蓝牙自拍等方案.
除了1039外, YC1021是百度搜索时自动推荐的关键词, 有可能用得也很广泛.
无代码爬虫
搞了半天的PlayWright, 忽然想到这不应该有无代码的爬虫工具么? 比如叫数据采集器? Data Collector?
查了一下国内的火车头采集器和国外的有些采集器真的收费不菲, 然后就发现Chrome应用商店里有crx应用, 尝试了1个, 发现真香,哈哈.
名称: Instant Data Scraper 和 NoCoding Data Scraper - Easy Web Scraping
这里还有一篇文章https://zapier.com/blog/best-data-collection-apps/介绍了5个, 不过还没有细看.
Instant Data Scraper
尝试了Instant Data Scraper, 体验很好, 非常好用. 强烈推荐.
它的特点是可以对翻页表格数据和无限流数据进行爬取, 配置速度极快. 问题是不能爬取表格内的详情页.
基本使用方式: 点击try another table, 切换到数据区域后, 点击Locate "next" button, 选择下一页按钮, 如果是无限流页面,则选择无限流, 然后对列进行删减选择, 点击start crawling开始爬取.
| 网站 | 特殊爬取方式 |
|---|---|
| 淘宝 | 搜索关键词后, 需要把页面切换为列表显示方式. 可以爬到价格 |
| 京东 | 需要使用m.jd.com网址爬取, 无限流方式. 可以爬到价格 |
Web Scraper - Free Web Scraping
它就可以一级一级的深入到详情页爬取, 相对强大一些, 但配置起来也也要慢一些. 每一个要爬取的参数都要单独配置.
油猴
油猴里搜索scraper也有一些脚本. 有空可以体验.
杨红旭谈房贷要不要还完
讲得蛮好.
- 如果通胀高于利率, 负债是有利的. 另外比如美国是负利率, 负债还能赚钱.
- 2008~2018年贷款是有折扣甚至是低于五年期LPR 4.6%的,都不用急着还钱. 公积金一定不用还, 利息只有3.25%. 2019年10月由个人基准贷款利率转变为LPR利率是比较高的,首套5.5%以上, 二套6%以上, 就不划算了, 可以早点还完.
- 在不同的城市有
普惠金融, 可以抵押房产获取4%的贷款, 这样可以换完申请这种低息贷款. - 如果
等额本息先还的是利息, 超过1/3, 再还是一样的.等额本金比较适合提交前还贷. - 有房贷的个税抵扣每个月可以抵扣1000元.
对主要能源的密度换算
主要能源对比
注意:都没有计算封装, 如装气的气管, 装油的油箱, 装电池的封装.装电池的封装应该体积和重量还是比较高的.
另外, 实际还需要考虑生产该项能源所需要花费的能量或者成本, 下面也没有列出来.
| 能源 | 比重(g/ml) | 比能或者热值(KJ/g) | 体积能量密度(KJ/ml) | 动力转换效率 | 有用功体积能量密度 |
|---|---|---|---|---|---|
| 液态氢 | 0.07 | 142 | 9.94 | - | - |
| 三元锂电池 | 2.5 | 0.9 | 2.25 | 0.9 | 2.025 |
| 磷酸铁锂电池 | 2.5 | 0.576 | 1.44 | 0.9 | 1.296 |
| 汽油 | 0.72 | 43.2 | 31.104 | 0.4 | 12.4416 |
| 柴油 | 0.84 | 42.7 | 35.868 | - | - |
| 天然气 | 0.44 | 47.8 | 21.032 | - | - |
| 石油气 | 0.58 | 47.5 | 27.55 | - | - |
| 石油 | 0.88 | 43 | 37.84 | - | - |
| 烟煤 | - | 26 | - | - | - |
单位换算
1大卡(千卡) = 4.19 千焦耳
1Wh(瓦时) = 3.6 千焦耳
以秦对比
| 参数 | 秦Plus EV电池 | 秦燃油版 |
|---|---|---|
| 重量kg | 382.57 | 28.08 |
| 能量密度Wh/kg | 140 | - |
| 电池容量71.7kWh | 53.56 | - |
| 续航km | 600 | 565.21 |
| 容积L | 223.12 | 39 |
| 百公里油耗L/100Km | - | 6.9 |
刀片电池参数
| 单片刀片电池参数 | 值 |
|---|---|
| 长m | 0.96 |
| 宽m | 0.09 |
| 厚m | 0.0135 |
| 体积L | 1.1664 |
| 重量kg | 2 |
| 密度kg/L | 1.71467764060357 |
playwright入门
参考文章
以下都是基于Python的. playwright也支持js和java
强大易用!新一代爬虫利器 Playwright 的介绍
playwright 爬虫使用, 这篇参考了上一篇, 算是学习笔记, 另外增加了cookie使用
Scraping the web with Playwright
官方文档
概述
Playwright用作爬虫入门最麻烦的就是, 一开始看官方介绍文档最费劲没用. 官方文档上来就是介绍怎么测试, 运行用的命令也不一样, 其实完全不需要那么麻烦.
安装
npm i playwright
正常的安装方式. 如果是官方文档 ,这一步就麻烦很多.
使用
官方文档上来就导入了test库, 而用于爬虫完全不需要. 以爬取eastmoney的新闻为例:
const playwright = require('playwright');
async function main() {
const browser = await playwright.chromium.launch({
headless: false // setting this to true will not run the UI
});
const page = await browser.newPage();
await page.goto('https://so.eastmoney.com/news/s?keyword=%E5%90%9B%E5%AE%9E%E7%94%9F%E7%89%A9');
const titles = await page.$$eval('.news_item', ele=>{
// return ele.innerText
let t = []
for(e of ele){
t.push({
title: e.querySelector('.news_item_t a').text,
link: e.querySelector('.news_item_t a').href,
time: e.querySelector('.news_item_time').textContent,
})
}
return t
})
console.log(titles)
await page.waitForTimeout(5000); // wait for 5 seconds
await browser.close();
}
main();
正式进入爬虫前有三步: 1. playwright打开浏览器; 2. 浏览器打开空页面; 3. 空页面打开网址;
正式爬虫就是用page.$eval或者page.$$eval函数从页面的上下文环境(等同于浏览器的console)中运行js并返回.
$eval相当于浏览器console中的$, 而$==document.querySelector, 必填参数第一个是选择器, 第二个是回调函数element=>{}, element是第一个选择到的元素
$$eval相当于浏览器console中的$$, 而$$==document.querySelectorAll, , 必填参数第一个是选择器, 第二个是回调函数elements=>{}, elements是选择到的所有元素数组.
然后在console环境整理好所有内容, return出来就好了.
这一步真的so easy, 比scrapy+splash+scrapy_splash不要强太多.
但值得注意的一点是, 很多网站上都是用了jquery导致$被jquery占用后无法正常选择,这时候还是老老实实用回document.querySelector吧
神器 selectorgadget
用这个做选择器非常舒爽
代码结构优化
const playwright = require('playwright');
async function main() {
const browser = await playwright.chromium.launch({
headless: false // setting this to true will not run the UI
});
const page = await browser.newPage();
await page.goto('https://so.eastmoney.com/news/s?keyword=%E5%90%9B%E5%AE%9E%E7%94%9F%E7%89%A9');
await scraper(page)
await scraper(page)
await page.waitForTimeout(5000); // wait for 5 seconds
await browser.close();
}
async function scraper(page){
let titles = await page.$eval('body', scraperCb)
console.log(titles)
await page.waitForTimeout(500); // wait for 5 seconds
}
function scraperCb(body){
let t = []
function getTitles(){
let ele = body.querySelectorAll('.news_item')
for(e of ele){
t.push({
title: e.querySelector('.news_item_t a').text,
link: e.querySelector('.news_item_t a').href,
time: e.querySelector('.news_item_time').textContent,
})
}
}
getTitles()
body.querySelector('.fydot~ a+ a').click()
return t
}
main();
改成三个函数的结构:
- main函数: 负责进入页面, 循环运行爬虫抓取下一页
- scraper函数: 负责运行$eval函数, 获取页面返回值, 并点击下一页, 等待执行完毕.
- scraperCb函数: 为$eval回调的函数, 内容在页面上下文运行, 其中的变量与爬虫主程序完全隔离.
另外, scraper函数选择器改为body, 便于在回调函数中抓取并处理所有的元素