<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: wxfwxf911</title>
    <description>The latest articles on DEV Community by wxfwxf911 (@wxfwxf911).</description>
    <link>https://dev.to/wxfwxf911</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4005286%2F150ac00e-37a8-49da-9135-7168bc947731.png</url>
      <title>DEV Community: wxfwxf911</title>
      <link>https://dev.to/wxfwxf911</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wxfwxf911"/>
    <language>en</language>
    <item>
      <title>爬虫被 React 反爬拦死？知乎 Draft.js 编辑器的完整破解过程（附代码）</title>
      <dc:creator>wxfwxf911</dc:creator>
      <pubDate>Sun, 16 Aug 2026 04:12:23 +0000</pubDate>
      <link>https://dev.to/wxfwxf911/pa-chong-bei-react-fan-pa-lan-si-zhi-hu-draftjs-bian-ji-qi-de-wan-zheng-po-jie-guo-cheng-fu-dai-ma--c0a</link>
      <guid>https://dev.to/wxfwxf911/pa-chong-bei-react-fan-pa-lan-si-zhi-hu-draftjs-bian-ji-qi-de-wan-zheng-po-jie-guo-cheng-fu-dai-ma--c0a</guid>
      <description>&lt;p&gt;做自动化发布的时候，知乎是我卡得最久的一个平台——不是登录、不是风控，而是&lt;strong&gt;编辑器本身把我拦死了&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;需求很简单：把 Markdown 文章自动发到知乎。结果内容怎么都进不去编辑器，提交一按，正文是空的。前前后后折腾了三个小时，最后发现根子在 React 上。整个过程记下来，给后来的人省点时间。&lt;/p&gt;

&lt;h3&gt;
  
  
  现象：内容塞进去了，一提交就丢
&lt;/h3&gt;

&lt;p&gt;一开始我图省事，直接改 DOM：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.DraftEditor-root .public-DraftEditor-content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;contentHtml&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;页面上看着明明显示出来了，一点「发布」，正文却是空的，或者只剩旧内容。你甚至能肉眼看到文字一闪，然后没了。&lt;/p&gt;

&lt;h3&gt;
  
  
  根因：Draft.js 是 React 受控组件，它不认你的 DOM
&lt;/h3&gt;

&lt;p&gt;知乎的编辑器底层是 &lt;strong&gt;Draft.js&lt;/strong&gt;，这是 React 官方出的富文本框架。它内部维护着一份自己的 state（编辑状态），页面上的文字是从这份 state &lt;strong&gt;渲染&lt;/strong&gt;出来的。&lt;/p&gt;

&lt;p&gt;这意味着：你直接改 &lt;code&gt;innerHTML&lt;/code&gt;，改的是浏览器里渲染出来的结果，但 React 那份 state 压根没变。等你触发提交，React 用自己 state 重新渲染，你塞进去的东西就全被「抹」回去了。&lt;/p&gt;

&lt;p&gt;打个比方：你以为改了账本，其实你只是拿笔在账本的复印件上写了字，原件一个字没动。&lt;/p&gt;

&lt;h3&gt;
  
  
  破解关键：别走 DOM，走「事件」
&lt;/h3&gt;

&lt;p&gt;React 不认直接赋值，但认&lt;strong&gt;合成事件&lt;/strong&gt;。它监听的是浏览器的输入事件，而不是 DOM 的变化。所以正确的做法是：&lt;strong&gt;模拟一次真实的键盘输入&lt;/strong&gt;，让 React 自己把这笔输入记进 state。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 先让编辑器获得焦点（点击一下）&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.DraftEditor-root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// 用 insertText 模拟键盘输入，触发 React 合成事件&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keyboard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;就这一句 &lt;code&gt;insertText()&lt;/code&gt;，把 &lt;code&gt;innerHTML&lt;/code&gt; 换成它，内容就进去了，提交也不丢了。&lt;/p&gt;

&lt;h3&gt;
  
  
  完整可跑通的代码
&lt;/h3&gt;

&lt;p&gt;下面是发布知乎文章的完整片段（Playwright + Python）：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;playwright.sync_api&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sync_playwright&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;publish_zhihu&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;sync_playwright&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;browser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chromium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;headless&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# 知乎反爬，建议 headful
&lt;/span&gt;        &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new_page&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://zhuanlan.zhihu.com/write&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# 填标题
&lt;/span&gt;        &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.WriteIndex-titleInput&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# 填正文：先点编辑器获得焦点，再模拟键盘输入
&lt;/span&gt;        &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.DraftEditor-root&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keyboard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insert_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# 点发布
&lt;/span&gt;        &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;button:has-text(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;发布&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;几个关键点：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;headless=False&lt;/code&gt;——知乎对无头浏览器检测很严，用有头模式成功率高得多。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;insert_text()&lt;/code&gt; 是核心，&lt;code&gt;fill()&lt;/code&gt; 对 React 受控组件经常失效。&lt;/li&gt;
&lt;li&gt;别用固定 &lt;code&gt;sleep&lt;/code&gt;，等「发布成功」的状态元素出现再结束，比瞎等可靠。&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  这套思路通用
&lt;/h3&gt;

&lt;p&gt;凡是「你改了 DOM 但页面不认」的场景，基本都是 React / Vue 这类框架的受控组件在作怪。记住一条：&lt;strong&gt;框架维护状态的场景，一律走事件，不走赋值。&lt;/strong&gt; 知乎是 Draft.js，其他平台也有各自的富文本框架，思路都一样。&lt;/p&gt;




&lt;p&gt;做数据采集、自动化脚本、多平台发布的朋友，如果你也被某个平台的反爬卡住了，欢迎来找我聊聊。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;接单范围&lt;/strong&gt;：Python 脚本定制、数据采集（含反爬破解）、自动化代做、多平台自动发布。&lt;strong&gt;闲鱼直接搜「反爬 数据采集」就能找到我&lt;/strong&gt;，或者 CSDN 站内私信，说明你的需求，我看到了就回。&lt;/p&gt;




</description>
      <category>python</category>
      <category>爬虫</category>
      <category>反爬</category>
      <category>react</category>
    </item>
    <item>
      <title>反爬不是玄学：我被 6 个平台毒打后，总结的一套破解方法论</title>
      <dc:creator>wxfwxf911</dc:creator>
      <pubDate>Fri, 14 Aug 2026 14:58:32 +0000</pubDate>
      <link>https://dev.to/wxfwxf911/fan-pa-bu-shi-xuan-xue-wo-bei-6-ge-ping-tai-du-da-hou-zong-jie-de-tao-po-jie-fang-fa-lun-13gk</link>
      <guid>https://dev.to/wxfwxf911/fan-pa-bu-shi-xuan-xue-wo-bei-6-ge-ping-tai-du-da-hou-zong-jie-de-tao-po-jie-fang-fa-lun-13gk</guid>
      <description>&lt;p&gt;做自动化、爬数据的人，最常问的一句话是：「为什么同一个脚本，在别人那儿能跑，到我这就不行？」&lt;/p&gt;

&lt;p&gt;其实反爬不是玄学。它本质是平台在判断「你到底是不是人」，而识别手段翻来覆去就那几类。我把踩过的坑归成四类，每一类给一套破解套路。摸清楚这四类，市面上大部分站你都能啃下来。&lt;/p&gt;

&lt;h3&gt;
  
  
  第一类：前端框架拦截（React 系）——你以为改好了，它根本不认
&lt;/h3&gt;

&lt;p&gt;典型症状：你 &lt;code&gt;innerHTML&lt;/code&gt; 塞进去的内容，一提交就丢了，或者点按钮没反应。&lt;/p&gt;

&lt;p&gt;知乎的编辑器底层是 Draft.js（React 富文本框架）。它内部维护着自己的 state，你直接改 DOM，React 完全不知道，下次渲染又给你盖回去。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;破解套路&lt;/strong&gt;：别直接改 DOM，把输入「喂」给框架。React 认合成事件，不认原生赋值。比如：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.DraftEditor-root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keyboard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;insertText()&lt;/code&gt; 会触发 React 的合成事件，Draft.js 这才认这笔输入。一句话：&lt;strong&gt;框架维护状态的场景，一律走事件，不走赋值。&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  第二类：DOM 隔离（Shadow DOM / 微前端）——querySelector 全是 null
&lt;/h3&gt;

&lt;p&gt;典型症状：元素肉眼可见，但 &lt;code&gt;document.querySelector()&lt;/code&gt; 一个都找不到。&lt;/p&gt;

&lt;p&gt;微信视频号用了个叫 wujie 的微前端框架，页面全塞在 &lt;code&gt;&amp;lt;wujie-app&amp;gt;&lt;/code&gt; 的 Shadow DOM 里。普通的 CSS 选择器全部失效，你会怀疑自己是不是打开了错误的页面。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;破解套路&lt;/strong&gt;：先穿透 shadowRoot，拿到真正的根节点，再往下找：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shadowRoot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wujie-app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;shadowRoot&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;记住：&lt;strong&gt;选择器失效时，先检查是不是被 Shadow DOM 隔开了&lt;/strong&gt;，别急着怀疑反爬。&lt;/p&gt;

&lt;h3&gt;
  
  
  第三类：WAF / 网关拦截——请求直接给你打回来
&lt;/h3&gt;

&lt;p&gt;典型症状：整个页面都进不去，统一返回个 4xx，或者一直转圈。&lt;/p&gt;

&lt;p&gt;思否上了 Safeline WAF，自动化请求统一回 HTTP 468。我试过 headless、headful、换 UA、加 stealth，全被 JS Challenge 卡在门外。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;破解套路&lt;/strong&gt;：先分清是「JS Challenge」还是「IP 封禁」——这俩解法完全不同。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JS Challenge：只能真浏览器 + human-like 慢速操作 + stealth 插件，让它觉得你是人。&lt;/li&gt;
&lt;li&gt;IP 封禁：换代理，本地直连基本无解。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这类最考验判断力。&lt;strong&gt;硬刚不动的时候，别死磕，绕过或者人工兜底，效率反而更高。&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  第四类：复杂异步流程——你以为传完了，其实没有
&lt;/h3&gt;

&lt;p&gt;典型症状：文件「上传成功」了，结果发布是空的。&lt;/p&gt;

&lt;p&gt;B站视频上传是分片的，你等 &lt;code&gt;input&lt;/code&gt; 事件触发没用——文件传上去之后，它还要在后台转码。得等到「重新上传」按钮出现，才算真正传完：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitForSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.upload-reencode-btn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300000&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;破解套路&lt;/strong&gt;：&lt;strong&gt;永远用状态信号，不用固定 sleep。&lt;/strong&gt; 固定 sleep 要么浪费时间，要么还没好就继续跑。等「完成」标志出现，才是真的完成。&lt;/p&gt;




&lt;p&gt;这四类对应了四种反爬思路：&lt;strong&gt;前端事件拦截、DOM 隔离、WAF 拦截、复杂异步&lt;/strong&gt;。做自动化的，几乎都会撞上其中一两个。核心其实就一句：&lt;strong&gt;反爬打的是「识别你是脚本」，你打的牌是「装得像人」——走事件、穿 DOM、真浏览器、等状态，这套组合拳能破大半。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;如果你也被某个平台的反爬卡住，或者想找人代做数据采集、自动化脚本、多平台内容分发，欢迎私聊交流。我平时也接这类私活，有需求可以直接私信，或者到我闲鱼上看看。&lt;/p&gt;




</description>
      <category>playwright</category>
      <category>反爬</category>
      <category>爬虫</category>
      <category>自动化</category>
    </item>
    <item>
      <title>用 Playwright 做数据采集，真正难的从来不是点击</title>
      <dc:creator>wxfwxf911</dc:creator>
      <pubDate>Fri, 14 Aug 2026 03:21:49 +0000</pubDate>
      <link>https://dev.to/wxfwxf911/yong-playwright-zuo-shu-ju-cai-ji-zhen-zheng-nan-de-cong-lai-bu-shi-dian-ji-2aoa</link>
      <guid>https://dev.to/wxfwxf911/yong-playwright-zuo-shu-ju-cai-ji-zhen-zheng-nan-de-cong-lai-bu-shi-dian-ji-2aoa</guid>
      <description>&lt;p&gt;很多人以为会 page.click() 和 page.fill() 就等于会做数据采集了。真上手一个项目才发现，点击、输入只占 20%，剩下 80% 全是下面这些「看不见的坑」。&lt;/p&gt;

&lt;p&gt;一、登录态管理，才是第一道坎&lt;br&gt;
目标网站要登录才能看数据，你总不能每次跑都手动扫码。核心是 Cookie 的生命周期管理：&lt;/p&gt;

&lt;h1&gt;
  
  
  首次手动登录，保存 cookie
&lt;/h1&gt;

&lt;p&gt;context = browser.new_context()&lt;br&gt;
page = context.new_page()&lt;/p&gt;

&lt;h1&gt;
  
  
  ... 手动登录后
&lt;/h1&gt;

&lt;p&gt;context.storage_state(path="cookies.json")&lt;/p&gt;

&lt;h1&gt;
  
  
  之后直接复用，跳过登录
&lt;/h1&gt;

&lt;p&gt;context = browser.new_context(storage_state="cookies.json")&lt;br&gt;
但保存一次就完事是错的。Cookie 会过期、会失效，脚本要能检测登录态是否还在，失效了及时提醒重新登录，而不是跑一半报一堆看不懂的错。&lt;/p&gt;

&lt;p&gt;二、指纹一致性，比你想的阴险&lt;br&gt;
很多网站不只看 UA，还查 navigator.webdriver、window.chrome、Canvas 指纹、甚至鼠标移动轨迹。你 headless 一开，指纹就露馅了。&lt;/p&gt;

&lt;p&gt;关键不是「加 stealth 插件」这么简单，而是保持整套指纹的自洽——UA、屏幕分辨率、语言、时区要像一个真实用户，不能东拼西凑。&lt;/p&gt;

&lt;p&gt;三、等待，是技术活不是 sleep&lt;br&gt;
新手最爱 time.sleep(5)，结果要么等不够、要么浪费半天。真正该做的是等条件，不等时间：&lt;/p&gt;

&lt;h1&gt;
  
  
  差：固定睡 5 秒
&lt;/h1&gt;

&lt;p&gt;time.sleep(5)&lt;/p&gt;

&lt;h1&gt;
  
  
  好：等某个元素真的出现
&lt;/h1&gt;

&lt;p&gt;page.wait_for_selector('.data-table', state='visible', timeout=30000)&lt;br&gt;
数据是异步加载的，等「数据渲染完成」这个信号，比等「几秒钟」可靠一百倍。&lt;/p&gt;

&lt;p&gt;四、稳定性，决定你能不能接第二单&lt;br&gt;
脚本跑一次成功没用，要能跑一百次都稳。三个关键：&lt;/p&gt;

&lt;p&gt;重试机制：网络抖动、偶发超时，自动重试而不是直接崩&lt;br&gt;
断点续跑：跑到一半断了，下次从断点接着跑，不从头再来&lt;br&gt;
日志：每次跑留下记录，出问题了能查，而不是对着黑屏猜&lt;br&gt;
这四点做扎实了，才是一个「能交付」的数据采集脚本，而不是「在我电脑上能跑」的 demo。&lt;/p&gt;

&lt;p&gt;后续我会继续分享自动化实战里的这些细节。如果你也在做类似的项目，卡在某个环节上，欢迎一起交流。&lt;/p&gt;

</description>
    </item>
    <item>
      <title>标题：爬数据 / 做自动化最怕反爬？我在 6 个平台上踩过的坑，全给你</title>
      <dc:creator>wxfwxf911</dc:creator>
      <pubDate>Thu, 13 Aug 2026 14:58:22 +0000</pubDate>
      <link>https://dev.to/wxfwxf911/biao-ti-pa-shu-ju-zuo-zi-dong-hua-zui-pa-fan-pa-wo-zai-6-ge-ping-tai-shang-cai-guo-de-keng-quan-gei-ni-oih</link>
      <guid>https://dev.to/wxfwxf911/biao-ti-pa-shu-ju-zuo-zi-dong-hua-zui-pa-fan-pa-wo-zai-6-ge-ping-tai-shang-cai-guo-de-keng-quan-gei-ni-oih</guid>
      <description>&lt;p&gt;做自动化的人都知道，写代码不难，难的是跟平台的反爬斗。最近我用 Playwright 做了一个多平台自动发布的工具，把国内主流的几个平台挨个打通了一遍。回头一看，这些坑一个比一个阴间，不踩一遍你根本想不到。挑四个最经典的说说。&lt;/p&gt;

&lt;p&gt;一、知乎：富文本编辑器根本不认 innerHTML&lt;br&gt;
知乎的文章编辑器底层是 Draft.js（React 的富文本框架）。一开始我图省事，直接 innerHTML = content，结果提交的时候内容直接丢了——Draft.js 内部维护着自己的 state，你改 DOM 它根本不认。&lt;/p&gt;

&lt;p&gt;最后只能模拟键盘输入：&lt;/p&gt;

&lt;p&gt;await page.click('.DraftEditor-root');&lt;br&gt;
await page.keyboard.insertText(content);&lt;br&gt;
insertText() 会触发 React 的合成事件，Draft.js 才认这笔输入。就这一下，卡了我大半天。&lt;/p&gt;

&lt;p&gt;二、微信视频号：DOM 藏在 Shadow DOM 里&lt;br&gt;
视频号用了个叫 wujie 的微前端框架，页面结构全塞在  的 Shadow DOM 里。普通的 document.querySelector() 全是 null，CSS 选择器全部失效。&lt;/p&gt;

&lt;p&gt;得先穿透进去：&lt;/p&gt;

&lt;p&gt;const shadowRoot = await page.evaluate(() =&amp;gt;&lt;br&gt;
  document.querySelector('wujie-app').shadowRoot&lt;br&gt;
);&lt;br&gt;
三、思否：WAF 直接把你整个自动化拦死&lt;br&gt;
思否上了 Safeline WAF，自动化请求统一返回 HTTP 468。我试过 headless、headful、换 UA、加 stealth，全被 JS Challenge 卡在门外。这种不是技术能硬刚的，只能绕过或者人工介入。&lt;/p&gt;

&lt;p&gt;四、B站：视频上传完 ≠ 传完了&lt;br&gt;
B站的视频上传是分片的，你等 input 事件触发没用，文件传上去之后它还要在后台转码。得等到「重新上传」按钮出现，才算真正上传完毕：&lt;/p&gt;

&lt;p&gt;await page.waitForSelector('.upload-reencode-btn', { timeout: 300000 });&lt;br&gt;
这还不算完，之后还要等转码进度条走完。一个视频发布流程，光"等"就要好几分钟。&lt;/p&gt;

&lt;p&gt;这四个坑，分别对应了四种不同的反爬思路：前端框架事件拦截（React）、DOM 隔离（Shadow DOM）、WAF 拦截、复杂异步流程。做自动化的，基本都会撞上其中一两个。&lt;/p&gt;

&lt;p&gt;如果你也在做类似的事——数据采集、自动化脚本、RPA、多平台内容分发——卡在某个平台上搞不定，欢迎私聊交流。&lt;/p&gt;

&lt;p&gt;另外我自己也接相关的私活：Python 脚本定制、数据采集、自动化代做、多平台自动发布，有需求可以直接私信。&lt;/p&gt;

</description>
    </item>
    <item>
      <title>开源项目从 0 到 1：我用 2 周业余时间搭建了多平台发布系统</title>
      <dc:creator>wxfwxf911</dc:creator>
      <pubDate>Wed, 12 Aug 2026 03:45:53 +0000</pubDate>
      <link>https://dev.to/wxfwxf911/kai-yuan-xiang-mu-cong-0-dao-1wo-yong-2-zhou-ye-yu-shi-jian-da-jian-liao-duo-ping-tai-fa-bu-xi-tong-2p4f</link>
      <guid>https://dev.to/wxfwxf911/kai-yuan-xiang-mu-cong-0-dao-1wo-yong-2-zhou-ye-yu-shi-jian-da-jian-liao-duo-ping-tai-fa-bu-xi-tong-2p4f</guid>
      <description>&lt;h1&gt;
  
  
  开源项目从 0 到 1：我是怎么用 2 周业余时间搭建多平台发布系统的
&lt;/h1&gt;

&lt;h2&gt;
  
  
  起因：一个周三晚上的崩溃
&lt;/h2&gt;

&lt;p&gt;故事开始于一个普通的周三晚上。&lt;/p&gt;

&lt;p&gt;22:00，写完了一篇 Python 教程。22:35，还在复制粘贴第 6 个平台。&lt;/p&gt;

&lt;p&gt;当时心里想的是：&lt;strong&gt;「我写了 40 分钟文章，为什么还要花 30 分钟发布？」&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;作为一个程序员的本能反应——这个问题应该用代码解决。&lt;/p&gt;

&lt;h2&gt;
  
  
  Day 1-2：技术选型
&lt;/h2&gt;

&lt;p&gt;动手之前花了两天调研。核心问题是：&lt;strong&gt;怎么跟 9 个平台对话？&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;经过调研发现，平台分三类：&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;代表&lt;/th&gt;
&lt;th&gt;方案&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;有公开 API&lt;/td&gt;
&lt;td&gt;掘金、CSDN、Dev.to&lt;/td&gt;
&lt;td&gt;HTTP 请求直接调&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;有半公开 API&lt;/td&gt;
&lt;td&gt;知乎、博客园&lt;/td&gt;
&lt;td&gt;需要逆向签名（x-zse-96、X-Ca）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;没有 API&lt;/td&gt;
&lt;td&gt;小红书、抖音&lt;/td&gt;
&lt;td&gt;只能 Playwright 浏览器模拟&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;技术栈决策：&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;后端: Python + FastAPI
  - 选 Python 因为 Playwright 的 Python 绑定最成熟
  - 选 FastAPI 因为异步支持好，自带文档

前端: 原生 HTML/CSS/JS
  - 不需要 React/Vue。一个管理后台而已，原生 JS 完全够用
  - 零 npm 依赖，部署简单

数据库: SQLite
  - 单文件，不需要装 MySQL/PostgreSQL
  - 个人工具，并发不是问题

浏览器插件: Chrome Extension Manifest V3
  - 一键提取 Cookie，用户不用手动 F12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;不做的事情：&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ 不用 Docker（增加复杂度，个人部署不需要）&lt;/li&gt;
&lt;li&gt;❌ 不用 Redis（SQLite 足够）&lt;/li&gt;
&lt;li&gt;❌ 不用前端框架（过度设计）&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Day 3-5：搭建骨架
&lt;/h2&gt;

&lt;p&gt;先搭最小可用版本：&lt;strong&gt;一个 API + 一个页面 + 一个平台&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;选掘金作为第一个平台——它有公开 API，最简单。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 核心抽象：每个平台一个 Adapter
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BasePlatform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;PublishResult&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nb"&gt;NotImplementedError&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_stats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;post_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;StatsResult&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nb"&gt;NotImplementedError&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;这个阶段的关键决策：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;策略模式&lt;/strong&gt;：每个平台是一个独立的 Adapter 类，新增平台不改核心逻辑&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;异步优先&lt;/strong&gt;：所有网络请求用 async/await，发布 9 个平台可以并发&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;失败隔离&lt;/strong&gt;：一个平台失败不影响其他平台&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;骨架搭完后，掘金能发了。但只有一个平台没意义——得把所有平台都接上。&lt;/p&gt;

&lt;h2&gt;
  
  
  Day 6-10：攻克硬骨头
&lt;/h2&gt;

&lt;h3&gt;
  
  
  知乎：逆向 x-zse-96 签名
&lt;/h3&gt;

&lt;p&gt;知乎的 API 要求每个请求带一个 &lt;code&gt;x-zse-96&lt;/code&gt; 签名头。签名的生成逻辑藏在知乎前端的混淆 JS 里。&lt;/p&gt;

&lt;p&gt;花了两个晚上逆向：原来是 &lt;strong&gt;MD5(特定参数 + d_c0 Cookie) → AES-CBC 加密 → 拼接前缀&lt;/strong&gt;。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_make_x_zse_96&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d_c0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;101_3_3.0+/api/v4/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;+&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;d_c0&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;md5_hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;md5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;# ... AES-CBC 加密 ...
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2.0_&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;encrypted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;搞定的那一刻，知乎文章秒发——那种感觉比写完代码还爽。&lt;/p&gt;

&lt;h3&gt;
  
  
  CSDN：阿里云网关签名
&lt;/h3&gt;

&lt;p&gt;CSDN 用的是阿里云 API 网关的 HMAC-SHA256 签名方案。文档是中文的，但签名串的格式写得很隐晦——分隔符必须是 &lt;code&gt;\n&lt;/code&gt;，不能是空格。这个细节浪费了我两个小时。&lt;/p&gt;

&lt;h3&gt;
  
  
  博客园：2002 年的 XML-RPC
&lt;/h3&gt;

&lt;p&gt;博客园的 API 是 MetaWeblog XML-RPC——一个 2002 年的协议。Python 标准库自带的 &lt;code&gt;xmlrpc.client&lt;/code&gt; 直接用。但有个坑：分类里不加 &lt;code&gt;[Markdown]&lt;/code&gt;，文章就会被当 HTML 解析。&lt;/p&gt;

&lt;h3&gt;
  
  
  小红书：Playwright 兜底
&lt;/h3&gt;

&lt;p&gt;小红书没有公开 API，只能上 Playwright。但每次启动浏览器要 2-3 秒。优化手段：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cookie 持久化，跳过登录&lt;/li&gt;
&lt;li&gt;先通过 API 拿到图片上传地址，只让 Playwright 做最后的表单提交&lt;/li&gt;
&lt;li&gt;在 Linux 服务器上用 Xvfb 虚拟显示&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Day 11-14：打磨产品
&lt;/h2&gt;

&lt;p&gt;核心功能跑通后，开始打磨：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;数据看板&lt;/strong&gt;：每个平台的阅读/点赞/评论自动汇总，不用挨个登录后台&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;浏览器插件&lt;/strong&gt;：一键提取 Cookie，告别手动 F12&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;错误处理&lt;/strong&gt;：发布失败自动重试，详细的错误日志&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;前端&lt;/strong&gt;：深紫渐变配色，告别 Bootstrap 蓝&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  踩过的坑（诚实版）
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;思否的雷池 WAF（HTTP 468）&lt;/strong&gt;——连 Playwright headful 模式都过不了，目前无解&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSDN 只能发草稿&lt;/strong&gt;——API 发布只有 status=2（草稿），要手动去后台点「发布」还要微信扫码&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;知乎 content/daily API 需要「致知计划」权限&lt;/strong&gt;——浪费半天调试，最后换了 &lt;code&gt;creations/v2/all&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev.to 反垃圾机制&lt;/strong&gt;——标题 5 分钟内不能重复，包括不同文章&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  数据和反馈
&lt;/h2&gt;

&lt;p&gt;两周开发，目前：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;9 个平台接入&lt;/li&gt;
&lt;li&gt;15 篇文章发布&lt;/li&gt;
&lt;li&gt;累计 143 阅读（掘金 23、知乎 50、CSDN 70）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;数字不大，但对于一个刚上线两天的开源项目来说，是个不错的开始。&lt;/p&gt;

&lt;h2&gt;
  
  
  下一步
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Docker 一键部署&lt;/li&gt;
&lt;li&gt;AI 内容改写（根据平台风格自动调整语气）&lt;/li&gt;
&lt;li&gt;海外平台支持（Medium、Hashnode）&lt;/li&gt;
&lt;li&gt;定时发布&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  最后
&lt;/h2&gt;

&lt;p&gt;这个项目让我体会到一件事：&lt;strong&gt;程序员最好的副业，是解决自己的问题&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;你自己就是用户，知道痛点在哪，不需要做用户调研。用着顺手了，开源出来——自然有人跟你一样需要它。&lt;/p&gt;

&lt;p&gt;如果你也在维护多个平台，或者想看看 Python + Playwright 怎么搞定 9 个平台的自动化：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 GitHub: &lt;a href="https://github.com/wxfwxf911/polypost" rel="noopener noreferrer"&gt;https://github.com/wxfwxf911/polypost&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Star ⭐ 是我持续维护的动力。如果有什么平台想让我支持，提 Issue。&lt;/p&gt;




&lt;p&gt;&lt;em&gt;标签：开源, Python, Playwright, 自动化, 独立开发&lt;/em&gt;&lt;/p&gt;

</description>
      <category>开源</category>
      <category>python</category>
      <category>playwright</category>
      <category>自动化</category>
    </item>
    <item>
      <title>Writing Takes 40 Minutes, Publishing Takes 30 — How I Automated Multi-Platform Content Distribution</title>
      <dc:creator>wxfwxf911</dc:creator>
      <pubDate>Wed, 12 Aug 2026 03:43:44 +0000</pubDate>
      <link>https://dev.to/wxfwxf911/writing-takes-40-minutes-publishing-takes-30-how-i-automated-multi-platform-content-distribution-3n55</link>
      <guid>https://dev.to/wxfwxf911/writing-takes-40-minutes-publishing-takes-30-how-i-automated-multi-platform-content-distribution-3n55</guid>
      <description>&lt;h1&gt;
  
  
  Writing Takes 40 Minutes, Publishing Takes 30 — How I Solved It
&lt;/h1&gt;

&lt;p&gt;Last Wednesday, 22:00. I just finished writing a tutorial on Python async programming — 2200 words, clean Markdown, syntax-highlighted code blocks.&lt;/p&gt;

&lt;p&gt;22:03, open Juejin. Paste title. Paste content. Code highlighting gone. Fix manually. Pick tags. Publish.&lt;/p&gt;

&lt;p&gt;22:08, open Zhihu. Paste title. Paste content. The Draft.js editor merged &lt;code&gt;async def&lt;/code&gt; into &lt;code&gt;asyncdef&lt;/code&gt;. Fix line by line. Publish.&lt;/p&gt;

&lt;p&gt;22:15, open CSDN. Paste title. Content looks fine. But the category dropdown has 50 options and "Python" is buried. Publish.&lt;/p&gt;

&lt;p&gt;22:20, open Cnblogs. Must add &lt;code&gt;[Markdown]&lt;/code&gt; tag to categories or the whole article renders as garbled HTML. Publish.&lt;/p&gt;

&lt;p&gt;22:25, open SegmentFault. Search tags for "Python async" — zero results. Type manually. Publish.&lt;/p&gt;

&lt;p&gt;22:30, open Dev.to. Translate title. Translate content. Publish.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Forty minutes to write. Thirty minutes to publish.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;22:35, all done. But the next morning, I wanted to check stats — another round of logging into each platform's dashboard one by one.&lt;/p&gt;

&lt;h2&gt;
  
  
  I'm Not Alone
&lt;/h2&gt;

&lt;p&gt;Searching forums and social platforms, I found many developers share this pain:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Every time I publish an article, I open 7-8 tabs, copy-paste 7-8 times, fix formatting 7-8 times. The joy of writing gets killed by the drudgery of publishing."&lt;/p&gt;

&lt;p&gt;"I usually only publish on one platform now. It's just too much work to do more. But then search engine exposure suffers."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why "Just Copy-Paste" Doesn't Work
&lt;/h2&gt;

&lt;p&gt;Each platform has a different editor:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Editor&lt;/th&gt;
&lt;th&gt;Markdown Handling&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Juejin&lt;/td&gt;
&lt;td&gt;Custom Markdown&lt;/td&gt;
&lt;td&gt;Good, but code highlighting sometimes breaks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zhihu&lt;/td&gt;
&lt;td&gt;Draft.js rich text&lt;/td&gt;
&lt;td&gt;No Markdown support, eats line breaks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSDN&lt;/td&gt;
&lt;td&gt;Dual-mode&lt;/td&gt;
&lt;td&gt;Mode switching corrupts formatting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cnblogs&lt;/td&gt;
&lt;td&gt;TinyMCE&lt;/td&gt;
&lt;td&gt;Must add &lt;code&gt;[Markdown]&lt;/code&gt; tag or disaster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SegmentFault&lt;/td&gt;
&lt;td&gt;Markdown&lt;/td&gt;
&lt;td&gt;Okay, but tag system is painful&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dev.to&lt;/td&gt;
&lt;td&gt;Markdown&lt;/td&gt;
&lt;td&gt;Best experience, but English-only audience&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The same Markdown renders differently everywhere. Copy-paste doesn't solve it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I spent two weeks of evenings building &lt;strong&gt;PolyPost&lt;/strong&gt; — an open-source tool that adapts your content for each platform and publishes everywhere with one click.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write once (Markdown)
      |
      v
  PolyPost adaptation layer
  |- Juejin -&amp;gt; Markdown -&amp;gt; API
  |- Zhihu -&amp;gt; Plain text -&amp;gt; Draft.js API
  |- CSDN -&amp;gt; HTML -&amp;gt; API with X-Ca signing
  |- Cnblogs -&amp;gt; Markdown -&amp;gt; MetaWeblog XML-RPC
  |- SegmentFault -&amp;gt; Plain text -&amp;gt; API
      |
      v
  All published in ~30 seconds
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Beyond Publishing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stats dashboard&lt;/strong&gt;: One page to see views/likes/comments across all platforms&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cookie manager&lt;/strong&gt;: Chrome extension for one-click session extraction&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scheduled publishing&lt;/strong&gt;: Queue posts for optimal timing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Publish history&lt;/strong&gt;: Track what went where&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Open Source
&lt;/h2&gt;

&lt;p&gt;Built with Python + FastAPI + Playwright. MIT licensed.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;GitHub: &lt;a href="https://github.com/wxfwxf911/polypost" rel="noopener noreferrer"&gt;https://github.com/wxfwxf911/polypost&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you maintain accounts on 5+ platforms, this saves you 30 minutes per article. If you only use 1-2 platforms, you probably don't need it.&lt;/p&gt;

&lt;p&gt;But if you're tired of the copy-paste-format-fix loop — give it a try.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Tags: #python #automation #productivity #opensource #writing&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>automation</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
    <item>
      <title>The Pain of Publishing to 9 Platforms — And How I Automated It Away</title>
      <dc:creator>wxfwxf911</dc:creator>
      <pubDate>Wed, 12 Aug 2026 03:35:31 +0000</pubDate>
      <link>https://dev.to/wxfwxf911/the-pain-of-publishing-to-9-platforms-and-how-i-automated-it-away-2p7p</link>
      <guid>https://dev.to/wxfwxf911/the-pain-of-publishing-to-9-platforms-and-how-i-automated-it-away-2p7p</guid>
      <description>&lt;h1&gt;
  
  
  写了 40 分钟文章，发了 30 分钟——程序员的发布困境终于有解了
&lt;/h1&gt;

&lt;h2&gt;
  
  
  一个周三晚上的真实记录
&lt;/h2&gt;

&lt;p&gt;22:00，写完了一篇 Python 异步编程的教程，2200 字，Markdown 格式，代码块带语法高亮。&lt;/p&gt;

&lt;p&gt;22:03，打开掘金。粘贴标题。粘贴正文。代码块的高亮没了。手动调整。选标签。发布。&lt;/p&gt;

&lt;p&gt;22:08，打开知乎。粘贴标题。粘贴正文。Draft.js 编辑器把 &lt;code&gt;async def&lt;/code&gt; 解析成了 &lt;code&gt;asyncdef&lt;/code&gt;。一段一段地修。发布。&lt;/p&gt;

&lt;p&gt;22:15，打开 CSDN。粘贴标题。正文正常了。但分类列表有 50 个选项，要找到"Python"得翻半天。发布。&lt;/p&gt;

&lt;p&gt;22:20，打开博客园。分类里要加 &lt;code&gt;[Markdown]&lt;/code&gt; 标签，不然文章会被当 HTML 解析。上次忘了加，整篇文章变成一团乱码。发布。&lt;/p&gt;

&lt;p&gt;22:25，打开思否。标签搜索"Python 异步"，返回 0 结果。手动输入。发布。&lt;/p&gt;

&lt;p&gt;22:30，打开 Dev.to。标题翻成英文。正文翻成英文。发布。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;写完文章用了 40 分钟，发布用了 30 分钟。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;22:35，终于全部发完。但第二天醒来，想看各平台数据——又得一个个登录后台。&lt;/p&gt;

&lt;h2&gt;
  
  
  我不是一个人
&lt;/h2&gt;

&lt;p&gt;在 V2EX、掘金、知乎上搜了一圈，发现这不是我一个人的痛苦：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"每次发文章都要打开七八个页面，复制粘贴七八次，调格式七八次。写完文章的高兴劲都被磨没了。"&lt;/em&gt;&lt;br&gt;
— V2EX 用户&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"我一般只发掘金，因为多发几个平台太累了。但只发掘金的话，文章在搜索引擎上的曝光又不够。"&lt;/em&gt;&lt;br&gt;
— 知乎回答&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"之前手动管理 4 个平台，后来放弃了只剩掘金。不是不想维护其他平台，是时间和精力不允许。"&lt;/em&gt;&lt;br&gt;
— 掘金沸点&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;程序员的发布困境&lt;/strong&gt;：写文章很开心，发布很痛苦，看数据更痛苦。&lt;/p&gt;

&lt;h2&gt;
  
  
  为什么"复制粘贴"解决不了？
&lt;/h2&gt;

&lt;p&gt;你可能想说：不就是 copy-paste 吗？能有多麻烦？&lt;/p&gt;

&lt;p&gt;问题是&lt;strong&gt;每个平台的编辑器都不一样&lt;/strong&gt;：&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;平台&lt;/th&gt;
&lt;th&gt;编辑器&lt;/th&gt;
&lt;th&gt;对 Markdown 的处理&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;掘金&lt;/td&gt;
&lt;td&gt;自研 Markdown 编辑器&lt;/td&gt;
&lt;td&gt;支持好，但代码块高亮有时丢失&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;知乎&lt;/td&gt;
&lt;td&gt;Draft.js 富文本&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;不支持 Markdown&lt;/strong&gt;，换行符被吃&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSDN&lt;/td&gt;
&lt;td&gt;富文本 + Markdown 双模&lt;/td&gt;
&lt;td&gt;切换模式容易乱&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;博客园&lt;/td&gt;
&lt;td&gt;TinyMCE&lt;/td&gt;
&lt;td&gt;不加 &lt;code&gt;[Markdown]&lt;/code&gt; 分类就当场爆炸&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;思否&lt;/td&gt;
&lt;td&gt;Markdown&lt;/td&gt;
&lt;td&gt;还可以，但标签系统难用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dev.to&lt;/td&gt;
&lt;td&gt;Markdown&lt;/td&gt;
&lt;td&gt;体验最好，英文平台&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;同一段 Markdown，在不同平台的表现完全不同。这不是复制粘贴能解决的。&lt;/p&gt;

&lt;h2&gt;
  
  
  自动化能做什么？
&lt;/h2&gt;

&lt;p&gt;我花了两个星期的业余时间，写了一个开源工具——&lt;strong&gt;PolyPost&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;核心逻辑很简单：&lt;strong&gt;你写一次 Markdown，它帮你适配到每个平台的格式要求，然后自动发布&lt;/strong&gt;。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;写文章（Markdown）
      │
      ▼
  PolyPost 适配层
  ├─ 掘金 → Markdown → API 发布
  ├─ 知乎 → 纯文本 → Draft.js API 发布
  ├─ CSDN → HTML → API + X-Ca 签名发布
  ├─ 博客园 → Markdown → MetaWeblog XML-RPC
  └─ 思否 → 纯文本 → API 发布
      │
      ▼
  全部发完，耗时 ≈ 30 秒
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  除了发布，还能做什么？
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;数据看板&lt;/strong&gt;：一个页面看所有平台的阅读/点赞/评论，不用一个个登录后台&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cookie 管理&lt;/strong&gt;：Chrome 浏览器插件一键提取登录态，不用手动 F12&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;定时发布&lt;/strong&gt;：写好了预约时间发，配合平台流量高峰&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;发布记录&lt;/strong&gt;：哪篇发了哪个平台，一目了然&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  开源 &amp;amp; 自部署
&lt;/h2&gt;

&lt;p&gt;PolyPost 是开源的（MIT License），你可以部署在自己的服务器上：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 GitHub: &lt;a href="https://github.com/wxfwxf911/polypost" rel="noopener noreferrer"&gt;https://github.com/wxfwxf911/polypost&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;目前支持 9 个平台：掘金、知乎、CSDN、博客园、思否、小红书、抖音、B站、微信视频号。&lt;/p&gt;

&lt;p&gt;如果你只用 3-4 个平台，可能不需要这个工具。但如果你像我一样维护 5+ 个平台，这 30 秒 vs 30 分钟的差距，每发一篇文章都能体会一次。&lt;/p&gt;

&lt;h2&gt;
  
  
  最后
&lt;/h2&gt;

&lt;p&gt;写代码是为了解决问题。自己的问题也是问题。&lt;/p&gt;

&lt;p&gt;如果你也被多平台发布折磨过，欢迎 Star ⭐ + 试用。如果你想支持更多平台，提个 Issue，我来适配。&lt;/p&gt;

&lt;p&gt;毕竟——写文章已经很累了，发布这件事，交给代码就好。&lt;/p&gt;




&lt;p&gt;&lt;em&gt;#Python #自动化 #效率工具 #开源 #技术写作&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>automation</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
    <item>
      <title>写了 40 分钟文章，发了 30 分钟——程序员的发布困境终于有解了</title>
      <dc:creator>wxfwxf911</dc:creator>
      <pubDate>Tue, 11 Aug 2026 17:18:05 +0000</pubDate>
      <link>https://dev.to/wxfwxf911/xie-liao-40-fen-zhong-wen-zhang-fa-liao-30-fen-zhong-cheng-xu-yuan-de-fa-bu-kun-jing-zhong-yu-you-jie-liao-2ink</link>
      <guid>https://dev.to/wxfwxf911/xie-liao-40-fen-zhong-wen-zhang-fa-liao-30-fen-zhong-cheng-xu-yuan-de-fa-bu-kun-jing-zhong-yu-you-jie-liao-2ink</guid>
      <description>&lt;h1&gt;
  
  
  写了 40 分钟文章，发了 30 分钟——程序员的发布困境终于有解了
&lt;/h1&gt;

&lt;h2&gt;
  
  
  一个周三晚上的真实记录
&lt;/h2&gt;

&lt;p&gt;22:00，写完了一篇 Python 异步编程的教程，2200 字，Markdown 格式，代码块带语法高亮。&lt;/p&gt;

&lt;p&gt;22:03，打开掘金。粘贴标题。粘贴正文。代码块的高亮没了。手动调整。选标签。发布。&lt;/p&gt;

&lt;p&gt;22:08，打开知乎。粘贴标题。粘贴正文。Draft.js 编辑器把 &lt;code&gt;async def&lt;/code&gt; 解析成了 &lt;code&gt;asyncdef&lt;/code&gt;。一段一段地修。发布。&lt;/p&gt;

&lt;p&gt;22:15，打开 CSDN。粘贴标题。正文正常了。但分类列表有 50 个选项，要找到"Python"得翻半天。发布。&lt;/p&gt;

&lt;p&gt;22:20，打开博客园。分类里要加 &lt;code&gt;[Markdown]&lt;/code&gt; 标签，不然文章会被当 HTML 解析。上次忘了加，整篇文章变成一团乱码。发布。&lt;/p&gt;

&lt;p&gt;22:25，打开思否。标签搜索"Python 异步"，返回 0 结果。手动输入。发布。&lt;/p&gt;

&lt;p&gt;22:30，打开 Dev.to。标题翻成英文。正文翻成英文。发布。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;写完文章用了 40 分钟，发布用了 30 分钟。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;22:35，终于全部发完。但第二天醒来，想看各平台数据——又得一个个登录后台。&lt;/p&gt;

&lt;h2&gt;
  
  
  我不是一个人
&lt;/h2&gt;

&lt;p&gt;在 V2EX、掘金、知乎上搜了一圈，发现这不是我一个人的痛苦：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"每次发文章都要打开七八个页面，复制粘贴七八次，调格式七八次。写完文章的高兴劲都被磨没了。"&lt;/em&gt;&lt;br&gt;
— V2EX 用户&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"我一般只发掘金，因为多发几个平台太累了。但只发掘金的话，文章在搜索引擎上的曝光又不够。"&lt;/em&gt;&lt;br&gt;
— 知乎回答&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"之前手动管理 4 个平台，后来放弃了只剩掘金。不是不想维护其他平台，是时间和精力不允许。"&lt;/em&gt;&lt;br&gt;
— 掘金沸点&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;程序员的发布困境&lt;/strong&gt;：写文章很开心，发布很痛苦，看数据更痛苦。&lt;/p&gt;

&lt;h2&gt;
  
  
  为什么"复制粘贴"解决不了？
&lt;/h2&gt;

&lt;p&gt;你可能想说：不就是 copy-paste 吗？能有多麻烦？&lt;/p&gt;

&lt;p&gt;问题是&lt;strong&gt;每个平台的编辑器都不一样&lt;/strong&gt;：&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;平台&lt;/th&gt;
&lt;th&gt;编辑器&lt;/th&gt;
&lt;th&gt;对 Markdown 的处理&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;掘金&lt;/td&gt;
&lt;td&gt;自研 Markdown 编辑器&lt;/td&gt;
&lt;td&gt;支持好，但代码块高亮有时丢失&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;知乎&lt;/td&gt;
&lt;td&gt;Draft.js 富文本&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;不支持 Markdown&lt;/strong&gt;，换行符被吃&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSDN&lt;/td&gt;
&lt;td&gt;富文本 + Markdown 双模&lt;/td&gt;
&lt;td&gt;切换模式容易乱&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;博客园&lt;/td&gt;
&lt;td&gt;TinyMCE&lt;/td&gt;
&lt;td&gt;不加 &lt;code&gt;[Markdown]&lt;/code&gt; 分类就当场爆炸&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;思否&lt;/td&gt;
&lt;td&gt;Markdown&lt;/td&gt;
&lt;td&gt;还可以，但标签系统难用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dev.to&lt;/td&gt;
&lt;td&gt;Markdown&lt;/td&gt;
&lt;td&gt;体验最好，英文平台&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;同一段 Markdown，在不同平台的表现完全不同。这不是复制粘贴能解决的。&lt;/p&gt;

&lt;h2&gt;
  
  
  自动化能做什么？
&lt;/h2&gt;

&lt;p&gt;我花了两个星期的业余时间，写了一个开源工具——&lt;strong&gt;PolyPost&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;核心逻辑很简单：&lt;strong&gt;你写一次 Markdown，它帮你适配到每个平台的格式要求，然后自动发布&lt;/strong&gt;。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;写文章（Markdown）
      │
      ▼
  PolyPost 适配层
  ├─ 掘金 → Markdown → API 发布
  ├─ 知乎 → 纯文本 → Draft.js API 发布
  ├─ CSDN → HTML → API + X-Ca 签名发布
  ├─ 博客园 → Markdown → MetaWeblog XML-RPC
  └─ 思否 → 纯文本 → API 发布
      │
      ▼
  全部发完，耗时 ≈ 30 秒
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  除了发布，还能做什么？
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;数据看板&lt;/strong&gt;：一个页面看所有平台的阅读/点赞/评论，不用一个个登录后台&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cookie 管理&lt;/strong&gt;：Chrome 浏览器插件一键提取登录态，不用手动 F12&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;定时发布&lt;/strong&gt;：写好了预约时间发，配合平台流量高峰&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;发布记录&lt;/strong&gt;：哪篇发了哪个平台，一目了然&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  开源 &amp;amp; 自部署
&lt;/h2&gt;

&lt;p&gt;PolyPost 是开源的（MIT License），你可以部署在自己的服务器上：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 GitHub: &lt;a href="https://github.com/wxfwxf911/polypost" rel="noopener noreferrer"&gt;https://github.com/wxfwxf911/polypost&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;目前支持 9 个平台：掘金、知乎、CSDN、博客园、思否、小红书、抖音、B站、微信视频号。&lt;/p&gt;

&lt;p&gt;如果你只用 3-4 个平台，可能不需要这个工具。但如果你像我一样维护 5+ 个平台，这 30 秒 vs 30 分钟的差距，每发一篇文章都能体会一次。&lt;/p&gt;

&lt;h2&gt;
  
  
  最后
&lt;/h2&gt;

&lt;p&gt;写代码是为了解决问题。自己的问题也是问题。&lt;/p&gt;

&lt;p&gt;如果你也被多平台发布折磨过，欢迎 Star ⭐ + 试用。如果你想支持更多平台，提个 Issue，我来适配。&lt;/p&gt;

&lt;p&gt;毕竟——写文章已经很累了，发布这件事，交给代码就好。&lt;/p&gt;




&lt;p&gt;&lt;em&gt;#Python #自动化 #效率工具 #开源 #技术写作&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>自动化</category>
      <category>效率工具</category>
      <category>开源</category>
    </item>
    <item>
      <title>I Built a Tool to Publish to 9 Platforms with One Click - Here is How</title>
      <dc:creator>wxfwxf911</dc:creator>
      <pubDate>Tue, 11 Aug 2026 17:15:43 +0000</pubDate>
      <link>https://dev.to/wxfwxf911/i-built-a-tool-to-publish-to-9-platforms-with-one-click-here-is-how-57ba</link>
      <guid>https://dev.to/wxfwxf911/i-built-a-tool-to-publish-to-9-platforms-with-one-click-here-is-how-57ba</guid>
      <description>&lt;h1&gt;
  
  
  I Automated Publishing to 9 Platforms with Python + Playwright
&lt;/h1&gt;

&lt;p&gt;Writing the article takes 40 minutes. Publishing to 9 platforms takes another 30. So I built a tool to handle it automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Every tech blogger knows this pain:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Juejin → paste title → paste content → fix formatting → pick tags → publish&lt;/li&gt;
&lt;li&gt;Open Zhihu → paste title → paste content → fight with Draft.js eating line breaks → publish&lt;/li&gt;
&lt;li&gt;Open CSDN → paste title → paste content → set category → publish&lt;/li&gt;
&lt;li&gt;Open Cnblogs → remember to add &lt;code&gt;[Markdown]&lt;/code&gt; tag → paste everything → publish&lt;/li&gt;
&lt;li&gt;Repeat for SegmentFault, Xiaohongshu, Douyin, Bilibili, WeChat Video...&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Each platform has its own editor quirks.&lt;/strong&gt; Markdown that looks perfect on one platform breaks on another. Code blocks lose syntax highlighting. Line breaks multiply or disappear.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;PolyPost&lt;/strong&gt; — an open-source tool that publishes to all 9 platforms with a single click.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;GitHub: &lt;a href="https://github.com/wxfwxf911/polypost" rel="noopener noreferrer"&gt;https://github.com/wxfwxf911/polypost&lt;/a&gt; (⭐ star it if you find it useful!)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User writes Markdown once
        |
        v
Content adaptation layer (Markdown → HTML / Rich Text / Plain Text)
        |
        v
Platform adapters (Juejin, Zhihu, CSDN, Cnblogs...)
        |
        v
Platform APIs / Playwright browser automation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Interesting Parts
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Zhihu's Anti-Crawler Signature (x-zse-96)
&lt;/h3&gt;

&lt;p&gt;Zhihu requires a cryptographic signature on every API request. It's an AES-CBC encrypted MD5 hash with a fixed prefix and uses the &lt;code&gt;d_c0&lt;/code&gt; cookie value as part of the signed string. Had to reverse-engineer this from Zhihu's frontend JavaScript.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. CSDN's X-Ca HMAC-SHA256
&lt;/h3&gt;

&lt;p&gt;CSDN uses Alibaba Cloud's API Gateway signing mechanism — every request needs &lt;code&gt;X-Ca-Signature&lt;/code&gt;, &lt;code&gt;X-Ca-Nonce&lt;/code&gt;, and &lt;code&gt;X-Ca-Timestamp&lt;/code&gt; headers. The signing string must use &lt;code&gt;\n&lt;/code&gt; as the separator (not spaces!), which took me 2 hours to debug.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Cnblogs MetaWeblog XML-RPC
&lt;/h3&gt;

&lt;p&gt;One of the few platforms with a standard API — though it's the ancient XML-RPC protocol from 2002. And yes, you must include &lt;code&gt;[Markdown]&lt;/code&gt; in the categories or it parses your content as HTML. Not documented anywhere.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Playwright for Platforms Without APIs
&lt;/h3&gt;

&lt;p&gt;Some platforms (Xiaohongshu, Douyin) don't have public APIs. For those, PolyPost falls back to Playwright browser automation — injecting pre-extracted cookies, filling forms, and clicking submit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Tech&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Backend&lt;/td&gt;
&lt;td&gt;Python / FastAPI&lt;/td&gt;
&lt;td&gt;Async, fast, great docs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;Vanilla HTML/CSS/JS&lt;/td&gt;
&lt;td&gt;Zero npm dependencies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DB&lt;/td&gt;
&lt;td&gt;SQLite&lt;/td&gt;
&lt;td&gt;Single file, zero ops&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Browser Extension&lt;/td&gt;
&lt;td&gt;Chrome MV3&lt;/td&gt;
&lt;td&gt;One-click cookie extraction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fallback&lt;/td&gt;
&lt;td&gt;Playwright&lt;/td&gt;
&lt;td&gt;For platforms without APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;After two weeks of evening hacking, it works. I write an article, click publish, go make coffee, and when I come back it's on all 9 platforms.&lt;/p&gt;

&lt;p&gt;The tool handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatic format adaptation per platform&lt;/li&gt;
&lt;li&gt;Cookie management via browser extension&lt;/li&gt;
&lt;li&gt;Stats aggregation (views, likes, comments)&lt;/li&gt;
&lt;li&gt;Scheduled publishing (coming soon)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;Open source, MIT licensed:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/wxfwxf911/polypost" rel="noopener noreferrer"&gt;https://github.com/wxfwxf911/polypost&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you publish to multiple Chinese platforms, give it a try. If you want support for another platform, open an issue.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Tags: #python #playwright #automation #opensource #productivity&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>playwright</category>
      <category>automation</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I built a tool to publish to 9 platforms with one click — here is how</title>
      <dc:creator>wxfwxf911</dc:creator>
      <pubDate>Mon, 10 Aug 2026 17:28:58 +0000</pubDate>
      <link>https://dev.to/wxfwxf911/i-built-a-tool-to-publish-to-9-platforms-with-one-click-here-is-how-2kn</link>
      <guid>https://dev.to/wxfwxf911/i-built-a-tool-to-publish-to-9-platforms-with-one-click-here-is-how-2kn</guid>
      <description>&lt;p&gt;I write technical articles for a few Chinese platforms (Juejin, CSDN, Zhihu, SegmentFault, Cnblogs). Every time I publish, I have to log into each one, paste the title, paste the content, fix the formatting, and hit publish. Five platforms, same content, one hour gone.&lt;/p&gt;

&lt;p&gt;Last weekend I finally snapped. I built PolyPost.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;Write in Markdown once. Check the platforms you want. Click publish. It handles the rest.&lt;/p&gt;

&lt;p&gt;Under the hood it uses Playwright to control a real browser — opening each platform's publish page, filling in the title, body, and tags, then submitting. Each platform has its own adapter script to handle quirks like different editors, anti-bot detection, and cookie formats.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt;: Python FastAPI + JWT auth&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automation&lt;/strong&gt;: Playwright (Node.js child process)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database&lt;/strong&gt;: SQLite&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt;: Vanilla HTML/CSS/JS, no framework&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment&lt;/strong&gt;: Docker + Nginx&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Core is under 2000 lines. Claude Code wrote most of the boilerplate — I focused on the platform-specific debugging.&lt;/p&gt;

&lt;h2&gt;
  
  
  Platforms supported
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Articles&lt;/strong&gt;: Juejin, CSDN, Zhihu, SegmentFault, Cnblogs, Dev.to&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Video&lt;/strong&gt;: Bilibili, Douyin (TikTok China), WeChat Video&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Images/Text&lt;/strong&gt;: Xiaohongshu (RED)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to use
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Online&lt;/strong&gt;: &lt;a href="http://42.193.173.160" rel="noopener noreferrer"&gt;http://42.193.173.160&lt;/a&gt; (free registration)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-host&lt;/strong&gt;: &lt;code&gt;git clone&lt;/code&gt;, &lt;code&gt;pip install&lt;/code&gt;, configure cookies, run&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker&lt;/strong&gt;: One command deploy&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The real takeaway
&lt;/h2&gt;

&lt;p&gt;This project took two days. Two years ago it would have taken me two weeks. AI-assisted development is a multiplier — not because the AI is smarter, but because it handles the 80% of work that is just wiring things together.&lt;/p&gt;

&lt;p&gt;If you are not using AI in your dev workflow yet, start now. Not as a chatbot. As a coworker.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/wxfwxf911/polypost" rel="noopener noreferrer"&gt;https://github.com/wxfwxf911/polypost&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stars and PRs welcome.&lt;/p&gt;

</description>
      <category>python</category>
      <category>playwright</category>
      <category>automation</category>
      <category>opensource</category>
    </item>
    <item>
      <title>让 9 个平台的内容发布从 30 分钟变成 30 秒</title>
      <dc:creator>wxfwxf911</dc:creator>
      <pubDate>Sat, 08 Aug 2026 16:38:16 +0000</pubDate>
      <link>https://dev.to/wxfwxf911/rang-9-ge-ping-tai-de-nei-rong-fa-bu-cong-30-fen-zhong-bian-cheng-30-miao-5e3m</link>
      <guid>https://dev.to/wxfwxf911/rang-9-ge-ping-tai-de-nei-rong-fa-bu-cong-30-fen-zhong-bian-cheng-30-miao-5e3m</guid>
      <description>&lt;h2&gt;
  
  
  痛点
&lt;/h2&gt;

&lt;p&gt;每次写完技术文章，发布才是最痛苦的环节。我有 9 个平台的账号要维护：掘金、知乎、CSDN、博客园、思否、小红书、抖音、B站、微信视频号。&lt;/p&gt;

&lt;p&gt;过去的标准操作：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;打开掘金 → 粘贴标题 → 粘贴正文 → 选标签 → 发布&lt;/li&gt;
&lt;li&gt;打开知乎 → 粘贴标题 → 粘贴正文 → 调格式（Draft.js 各种吞换行）→ 发布&lt;/li&gt;
&lt;li&gt;打开 CSDN → 粘贴标题 → 粘贴正文 → 设分类 → 发布&lt;/li&gt;
&lt;li&gt;...重复 ×6&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;写文章 40 分钟，发布 30 分钟&lt;/strong&gt;。而且每次都要忍受不同平台编辑器的怪癖——有的不认 Markdown、有的吃空格、有的代码块语法高亮全丢。&lt;/p&gt;

&lt;p&gt;于是我写了个工具：&lt;strong&gt;PolyPost&lt;/strong&gt;。一次编辑，9 平台同步发布。开源。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;GitHub: &lt;a href="https://github.com/wxfwxf911/polypost" rel="noopener noreferrer"&gt;https://github.com/wxfwxf911/polypost&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  效果
&lt;/h2&gt;

&lt;p&gt;在 PolyPost 的编辑器里写好文章（支持 Markdown + 富文本），勾选要发布的平台，点一下「发布」按钮。后端自动完成格式转换和推送。&lt;/p&gt;

&lt;p&gt;对于不需要复杂交互的平台（掘金、CSDN、博客园、思否），直接调用 API 发布，秒级完成。对于需要浏览器操作的平台（知乎、小红书、抖音等），用 Playwright 模拟操作，但也比手动快得多——关键是&lt;strong&gt;你不用守着&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;同时附带一个 Chrome 浏览器插件，&lt;strong&gt;一键提取各平台 Cookie&lt;/strong&gt;，告别手工配置的麻烦。&lt;/p&gt;

&lt;h2&gt;
  
  
  技术实现
&lt;/h2&gt;

&lt;p&gt;后端：Python FastAPI + SQLite。前端：原生 HTML/CSS/JS（无框架依赖，体积极小）。&lt;/p&gt;

&lt;p&gt;支持平台及实现方式：&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;平台&lt;/th&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;实现方式&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;掘金&lt;/td&gt;
&lt;td&gt;文章&lt;/td&gt;
&lt;td&gt;HTTP API（Markdown 原生支持）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSDN&lt;/td&gt;
&lt;td&gt;文章&lt;/td&gt;
&lt;td&gt;HTTP API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;思否&lt;/td&gt;
&lt;td&gt;文章&lt;/td&gt;
&lt;td&gt;HTTP API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;博客园&lt;/td&gt;
&lt;td&gt;文章&lt;/td&gt;
&lt;td&gt;MetaWeblog API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;知乎&lt;/td&gt;
&lt;td&gt;文章&lt;/td&gt;
&lt;td&gt;Playwright 浏览器自动化&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;小红书&lt;/td&gt;
&lt;td&gt;图文&lt;/td&gt;
&lt;td&gt;Playwright 浏览器自动化&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;抖音&lt;/td&gt;
&lt;td&gt;视频&lt;/td&gt;
&lt;td&gt;Playwright 浏览器自动化&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B站&lt;/td&gt;
&lt;td&gt;视频&lt;/td&gt;
&lt;td&gt;Playwright 浏览器自动化&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;微信视频号&lt;/td&gt;
&lt;td&gt;视频&lt;/td&gt;
&lt;td&gt;Playwright + 微前端集成&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  一些有意思的技术细节
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;知乎&lt;/strong&gt; 使用 Draft.js 富文本编辑器，不能直接设 &lt;code&gt;innerHTML&lt;/code&gt;，必须用 &lt;code&gt;keyboard.insertText()&lt;/code&gt; 触发 React 合成事件&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;小红书&lt;/strong&gt; 是 Vue SPA，编辑器路由切换要走 Vue Router 内部导航&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;视频号&lt;/strong&gt; 用 wujie 微前端框架，DOM 藏在 &lt;code&gt;&amp;lt;wujie-app&amp;gt;&lt;/code&gt; 的 Shadow DOM 里，普通的 CSS 选择器全部失效&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;抖音&lt;/strong&gt; 登录页直接内嵌在发布页 URL 里，需要靠 body text 实时检测扫码状态&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;B站&lt;/strong&gt; 视频上传有独立的分片上传组件，要等「重新上传」按钮出现才算上传完毕，期间还需要等待转码&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;每个平台都是独立的小工程，做完之后再回头看，这些"脏活累活"才是自动化最能发挥价值的地方。&lt;/p&gt;

&lt;h2&gt;
  
  
  其他功能
&lt;/h2&gt;

&lt;p&gt;除了核心的一键多发，还陆续加了：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⏰ &lt;strong&gt;定时发布&lt;/strong&gt; — 可以预约发布时间，全自动&lt;/li&gt;
&lt;li&gt;📊 &lt;strong&gt;数据看板&lt;/strong&gt; — 实时统计发布成功率、各平台阅读量/点赞数&lt;/li&gt;
&lt;li&gt;👥 &lt;strong&gt;多账号管理&lt;/strong&gt; — 支持多个同平台账号切换&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;文章管理&lt;/strong&gt; — 已发布文章列表、重发、删除&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  为什么开源
&lt;/h2&gt;

&lt;p&gt;这个工具一开始只是为了解决自己的痛点。但后来发现很多做自媒体的朋友都有类似的困扰——内容分发是所有创作者绕不开的时间黑洞，但又不是每个人的核心业务，不值得花精力去优化。&lt;/p&gt;

&lt;p&gt;开源出来，希望更多的人能用上。也欢迎提 Issue 和 PR。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;GitHub 地址：&lt;a href="https://github.com/wxfwxf911/polypost" rel="noopener noreferrer"&gt;https://github.com/wxfwxf911/polypost&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;觉得有用的话，给个 Star ⭐️ 就是最大的鼓励&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  后续计划
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;海外平台接入（Medium / Dev.to / Hashnode / Reddit）&lt;/li&gt;
&lt;li&gt;文章翻译（中英互译，方便发海外平台）&lt;/li&gt;
&lt;li&gt;AI 辅助优化标题和摘要&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>我做了一个多平台自动分发工具，7个平台一键发布，数据实时追踪，分享开发心得</title>
      <dc:creator>wxfwxf911</dc:creator>
      <pubDate>Wed, 05 Aug 2026 12:51:02 +0000</pubDate>
      <link>https://dev.to/wxfwxf911/wo-zuo-liao-ge-duo-ping-tai-zi-dong-fen-fa-gong-ju-7ge-ping-tai-jian-fa-bu-shu-ju-shi-shi-zhui-zong-fen-xiang-kai-fa-xin-de-1hn5</link>
      <guid>https://dev.to/wxfwxf911/wo-zuo-liao-ge-duo-ping-tai-zi-dong-fen-fa-gong-ju-7ge-ping-tai-jian-fa-bu-shu-ju-shi-shi-zhui-zong-fen-xiang-kai-fa-xin-de-1hn5</guid>
      <description>&lt;p&gt;我是一个独立开发者，平时写博客需要在七八个平台之间来回粘贴排版，每次发布加修改格式至少要40分钟。久而久之就觉得很烦——能不能一次写好，一键发到所有平台？&lt;/p&gt;

&lt;p&gt;于是动手做了 PolyPost，一个多平台内容分发工具。&lt;/p&gt;

&lt;h2&gt;
  
  
  能做什么
&lt;/h2&gt;

&lt;p&gt;目前在7个平台跑通了发布和统计数据抓取：CSDN、掘金、知乎、Dev.to、SegmentFault、博客园、小红书。Medium 和 Hashnode 也在接入中。&lt;/p&gt;

&lt;p&gt;核心流程很简单：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;在编辑器写一篇 Markdown&lt;/li&gt;
&lt;li&gt;一键推送到所有平台（自动适配各平台的格式差异）&lt;/li&gt;
&lt;li&gt;每小时自动拉取各平台的阅读/点赞/评论数据&lt;/li&gt;
&lt;li&gt;仪表盘统一查看所有平台的实时数据&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  技术栈
&lt;/h2&gt;

&lt;p&gt;后端用的 FastAPI + SQLite，前端是原生 JS SPA。多平台发布的难点不在"发"，而在"适配"——每个平台都有自己的一套玩法：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;知乎&lt;/strong&gt;：Cookie 认证 + x-zse-96 签名算法（魔改 AES-CBC），文章发布要用 Playwright 浏览器自动化&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;掘金&lt;/strong&gt;：API 层面已经比较规范，但 detail API 返回 err_no=2，最后用 query_list 遍历才拿到统计数据&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSDN&lt;/strong&gt;：bizapi 只支持写入不支持读取，统计需要用 Phoenix 控制台 API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev.to&lt;/strong&gt;：官方 API 设计不错，但文章详情端点不返回 page_views_count，要切到 /articles/me 端点&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;小红书&lt;/strong&gt;：纯 Playwright 驱动，填表→一键排版→下一步→发布，每一步都像在拆盲盒&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;折腾下来最大的感悟是：&lt;strong&gt;做多平台工具的护城河不在功能本身，而在于踩完了所有平台的坑&lt;/strong&gt;。知乎那个 x-zse-96 的逆向、CSDN 的 Phoenix API 发现、小红书的五重发布按钮定位策略——这些东西不是看文档能搞定的，只能一个一个趟。&lt;/p&gt;

&lt;h2&gt;
  
  
  实际使用效果
&lt;/h2&gt;

&lt;p&gt;我自己用来发了 2 篇技术文章到 7 个平台，目前掘金显示 7 次阅读（其他平台因为文章较新或渠道差异数据还没起来）。但和之前手动分发相比，&lt;strong&gt;省下的时间才是真正的收益&lt;/strong&gt;——差不多每次省 30-40 分钟。&lt;/p&gt;

&lt;h2&gt;
  
  
  下一步计划
&lt;/h2&gt;

&lt;p&gt;这周刚把 PolyPost 从单用户改造成了多用户 SaaS，加了注册登录、免费/Pro 分层，准备对外运营。路线很清晰：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;免费版开放 3 个平台、每天 2 篇，让用户先体验到省时间的爽感&lt;/li&gt;
&lt;li&gt;Pro 版按月收费，全平台不限量&lt;/li&gt;
&lt;li&gt;用 PolyPost 自己发「自动化搞副业」系列文章来引流——产品自己就是最好的案例&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;如果你也是多平台写作者，欢迎体验。我们一起把手动分发的苦差事交给脚本。&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
