V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lijinma
V2EX  ›  Node.js

分享一个使用“代理”的方式抓取微信公众账号文章,可以抓阅读数,点赞数,赞赏数和回复数,使用 anyproxy

  •  2
     
  •   lijinma · 2017-04-05 21:02:03 +08:00 · 11846 次点击
    这是一个创建于 2787 天前的主题,其中的信息可能已经有所发展或是发生改变。

    首先,先看我写的文章,介绍现在微信公众账号可以抓取的方法:

    如何优雅的抓取微信公众号历史文章

    这个工具是纯 node.js 代码,使用 anyproxy 做代理来抓取文章的。

    安装:

    $ npm install wechat_spider -g
    

    具体安装和使用请查看 https://github.com/lijinma/wechat_spider

    抓取完存储在 sqlite 中,可以导出 csv ,如图:

    Alt text

    抓取思路:

    1. 使用中间人攻击的方式,安装根证书。
    2. 为了保证自动抓取分页,在每一页的后面添加:<script>setTimeout(function(){window.location.href="下一个 url";},2000);</script>,动态修改下一个 url ,这样就可以保证一直抓下去。

    这是一个完整的工具

    我尽可能的在 README 中尽可能的把每一步都写得非常清楚,希望真的可以对你有用,尤其是媒体工作者,因为我这个工具就是为我一个做媒体的朋友写的,有任何问题,请提 Issue 。

    我的公众账号

    text

    第 1 条附言  ·  2017-04-06 09:56:33 +08:00
    好多人收藏这个帖子,如果觉得有用,能给个 Star 吗。。。多谢。
    54 条回复    2017-04-10 01:11:10 +08:00
    lijinma
        1
    lijinma  
    OP
       2017-04-05 21:36:02 +08:00
    - 。- 没人理,睡觉去了
    anexplore
        2
    anexplore  
       2017-04-05 23:17:03 +08:00 via iPhone
    知乎上看过一样思路的文章 github 上有实现
    mingyun
        3
    mingyun  
       2017-04-05 23:26:31 +08:00
    安装失败了,不支持 py3
    gyp ERR! configure error
    gyp ERR! stack Error: Python executable "d:\python3\python.EXE" is v3.5.2, which
    is not supported by gyp.
    gyp ERR! stack You can pass the --python switch to point to Python >= v2.5.0 & <
    3.0.0.
    qiayue
        4
    qiayue  
       2017-04-05 23:42:37 +08:00
    @lijinma 做得挺好的,学习了
    sumuu
        5
    sumuu  
       2017-04-06 01:03:59 +08:00
    昨天也刚好做了一个抓取微信公众号的历史记录,不过实现方式有差异.

    直接分析 Windows 客户端,模拟请求抓取的.
    lijinma
        6
    lijinma  
    OP
       2017-04-06 05:46:32 +08:00
    @anexplore 嗯哪,我看到过 go 语言实现的。思路是一样的。
    lijinma
        7
    lijinma  
    OP
       2017-04-06 05:47:25 +08:00
    @mingyun ……哎,不开心,安装 sqlite 的时候需要 python2.*,我得赶紧改一下文档,谢谢你反馈。
    WildCat
        8
    WildCat  
       2017-04-06 06:30:23 +08:00 via iPhone
    @lijinma 大神能否发下 golang 实现的?
    mooncakejs
        9
    mooncakejs  
       2017-04-06 07:21:24 +08:00 via iPhone
    这个还是麻烦了, xposed 去 WebView 注入一个 js 文件,可以随便怎么玩。
    lijinma
        10
    lijinma  
    OP
       2017-04-06 09:35:27 +08:00   ❤️ 1
    lijinma
        11
    lijinma  
    OP
       2017-04-06 09:39:42 +08:00
    @sumuu 嘿嘿,我这个工具,用 Windows 客户端 Mac 客户端都可以用,但是客户端是拿不到阅读数和点赞数的吧。列表都可以拿到。
    lijinma
        12
    lijinma  
    OP
       2017-04-06 09:40:09 +08:00
    @mooncakejs 确实,但是一般人都可以玩玩, xposed 高端玩家可以玩。
    fhefh
        13
    fhefh  
       2017-04-06 09:50:04 +08:00
    谢谢楼主分享
    lijinma
        14
    lijinma  
    OP
       2017-04-06 10:15:11 +08:00
    @fhefh 客气~
    yangxiongguo
        15
    yangxiongguo  
       2017-04-06 10:19:10 +08:00
    感谢分享
    falseen
        16
    falseen  
       2017-04-06 10:19:37 +08:00 via Android
    其实不一定要用代理的,仔细观察可以发现,出现验证码之后只要清空缓存或是用隐身模式就可以不用输验证码。它的实现原理是在出现验证码的时候检测 cookie ,如果是初次打开,则利用 js 做一系列的运算,最终得到一个免验证码的 cookie 。

    我们可以利用这一点来绕过验证码。我曾经帮别人做过一个批量获取公众号文章的工具,就是利用这个方法实现的免验证码。我回头看一下有没有失效,如果没的话就把它放出来。
    lijinma
        17
    lijinma  
    OP
       2017-04-06 10:48:16 +08:00
    @falseen 恩恩,你说的是搜狗微信抓文章的,主要搜狗微信历史记录不全,而且 web 抓 不到点赞数和阅读数。才迫不得已使用代理的方式。
    falseen
        18
    falseen  
       2017-04-06 11:30:54 +08:00
    @lijinma 哦,我看错了。我还以为使用代理是为了绕过验证码呢~不好意思。你这个思路挺有意思的,赞一个!不过我有一个疑问,是不是每个公众号都要手动操作客户端 ?还是只要操作一次,之后就可以自动跳转了 ?
    lijinma
        19
    lijinma  
    OP
       2017-04-06 11:43:56 +08:00
    @falseen 可以的,但是我这个工具是没这么做的,我另外一个工具是这么做的,先采集好所有的公众号的 biz 参数,然后开始抓取,抓取完一个跳到另外一个账号的历史记录。

    但是我这个工具就是想弄的简单点,大家直接可以完,然后看我的代码自己改改就可以随便抓了。

    谢谢你的回复。
    MrFireAwayH
        20
    MrFireAwayH  
       2017-04-06 11:58:43 +08:00 via Android
    Win10 没法安装……显示没有 8.1 SDK 尝试了一些方案……还是没能解决😪😪😪
    lijinma
        21
    lijinma  
    OP
       2017-04-06 12:04:59 +08:00
    @MrFireAwayH 啊啊啊啊啊啊,你可以给我提个 issue 吗?把详细情况写一写,我想办法解决一下,虽然我用 Mac
    lijinma
        22
    lijinma  
    OP
       2017-04-06 13:41:11 +08:00
    @yangxiongguo 不客气
    MrFireAwayH
        23
    MrFireAwayH  
       2017-04-06 14:15:53 +08:00 via Android
    @lijinma 提了……不知道说的够不够清楚……嘛~总之麻烦啦
    lijinma
        24
    lijinma  
    OP
       2017-04-06 14:33:53 +08:00
    @MrFireAwayH 说清楚了,看你的报错,应该是缺少 Windows SDK version 8.1

    你试一下安装:

    https://developer.microsoft.com/en-us/windows/downloads/windows-8-1-sdk
    sundyli
        25
    sundyli  
       2017-04-06 15:08:00 +08:00
    我是 golang 版本的作者, 支持一下 wechat_spider nodejs 版本的开源
    lijinma
        26
    lijinma  
    OP
       2017-04-06 15:16:18 +08:00
    @sundyli 太感谢你了,谢谢你的代码 + 你的文档。
    MrFireAwayH
        27
    MrFireAwayH  
       2017-04-06 15:31:08 +08:00 via Android
    首先感谢分享 确实挺不错的……

    其次……我想知道如何停止任务😶

    不小心测试了一个火锅店……结果已经到 2014 年了……😂 停止程序也不能阻止
    lijinma
        28
    lijinma  
    OP
       2017-04-06 15:34:45 +08:00
    @MrFireAwayH 哈哈哈哈, mac 上 control + c 就能退出了吧。。。

    Windows 你看看,不行就找这个进程,杀掉。。
    MrFireAwayH
        29
    MrFireAwayH  
       2017-04-06 15:36:34 +08:00 via Android
    @lijinma 我的意思是……不能退出任务😂 Ctrl+c 确实可以终止 spider 不过……再次开启 spider 后 他会继续跑上次没完成的任务……也就是那个历史悠久的火锅店 哪怕我手机这边换了别人的公众号
    lijinma
        30
    lijinma  
    OP
       2017-04-06 15:45:34 +08:00
    @MrFireAwayH 噢噢噢噢,明白了。 你换一个目录:

    1. 跑列表的时候会生成一个 wechat.sqlite ,然后跑单个文章的是,从 wechat.sqlite 中拿那些没跑过的文章。

    所以你换一个目录,就会在这个目录建立一个新的数据库。

    我说明白了吗?
    MrFireAwayH
        31
    MrFireAwayH  
       2017-04-06 15:55:44 +08:00 via Android
    @lijinma OK 了~
    laoertongzhi
        32
    laoertongzhi  
       2017-04-06 16:25:44 +08:00
    感谢!
    lijinma
        33
    lijinma  
    OP
       2017-04-06 16:37:24 +08:00
    @laoertongzhi 客气,求个 Star..
    lijinma
        34
    lijinma  
    OP
       2017-04-06 17:03:26 +08:00
    @MrFireAwayH 你给的这个有问题的公众号奇怪了。。我等等有时间给你解决哈
    AlwaysBee
        35
    AlwaysBee  
       2017-04-06 17:18:58 +08:00
    支持支持,当初看了 go 的实现后还想自己写一个 node 版本的,现在不用了,哈哈
    AlwaysBee
        36
    AlwaysBee  
       2017-04-06 17:23:24 +08:00
    另外借个楼,推荐一个自己开发的 wordpress 插件,一键导入公众号文章,支持批量导入, http://artizen.me/beepress
    lijinma
        37
    lijinma  
    OP
       2017-04-06 17:26:04 +08:00
    @AlwaysBee 哈哈, node 有方便的 anyproxy ,确实很舒服。谢谢你的工具,我做的 xiaolai.co 可能和你是类似的原理吧,我用 Guzzle 爬的。
    AlwaysBee
        38
    AlwaysBee  
       2017-04-06 17:28:23 +08:00
    @lijinma 配合爬虫食用更佳
    lijinma
        39
    lijinma  
    OP
       2017-04-06 17:35:38 +08:00
    @AlwaysBee 是的,如果只是抓文章内容,只需要拿到文章 url ,然后自己爬就行了,但是我的媒体朋友需要点赞数,阅读数,赞赏数等。。。就没办法,只能代理客户端。
    AlwaysBee
        40
    AlwaysBee  
       2017-04-06 17:43:10 +08:00
    @lijinma 嗯,这些数据还要进行二次渲染,这个插件只是针对 wordpress ,方便用户,如果需要大量的导入的话那还是需要配合爬虫来进行比较高效,很不错,有 node 版本的
    lijinma
        41
    lijinma  
    OP
       2017-04-06 18:38:46 +08:00
    @AlwaysBee 嗯哪, web 版本的微信文章,随便爬,没什么限制。
    uglyer
        42
    uglyer  
       2017-04-06 19:05:14 +08:00
    写过一个类似的,不过抓取频率高了会被封号,不知道楼主有没有测试过一天能爬多少。
    MrFireAwayH
        43
    MrFireAwayH  
       2017-04-06 19:08:05 +08:00 via Android
    @lijinma 不着急 你能帮忙已经很感谢啦~😊
    AlwaysBee
        44
    AlwaysBee  
       2017-04-06 19:23:08 +08:00
    @uglyer 我用那个 go 的版本也被封过号,当时没玩多久就被封了,才爬了几个公众号而已,所以也不知道具体的原因,好在这只是小号
    uglyer
        45
    uglyer  
       2017-04-06 19:25:10 +08:00 via Android
    @AlwaysBee 养了一批号,好几台手机跑这个,出口都不同,全死光了。
    lijinma
        46
    lijinma  
    OP
       2017-04-06 20:53:07 +08:00
    @uglyer
    @AlwaysBee

    我只抓列表抓过几十万的数据,但是阅读数和点赞数没有这么抓过。。。
    hastelloy
        47
    hastelloy  
       2017-04-07 08:15:53 +08:00 via Android
    @falseen 大约是公元 2016 年年底的时候这种方式失效了,貌似是加入了 ip 记录的方式防止这个,我有个 python 版的代理大法
    hastelloy
        48
    hastelloy  
       2017-04-07 08:23:56 +08:00 via Android
    @lijinma 直接访问下文章页不是可以得到阅读数,点赞数什么的吗,
    lijinma
        49
    lijinma  
    OP
       2017-04-07 08:49:54 +08:00
    @hastelloy 当然可以,就是要批量的。
    bozong
        50
    bozong  
       2017-04-07 13:38:12 +08:00
    @mooncakejs #9 大牛
    MrFireAwayH
        51
    MrFireAwayH  
       2017-04-07 21:12:37 +08:00 via Android
    目前有一个情况是如果文章带有视频的话 会有大概率无限循环某两个文章

    经查发现 虽然微信页面是在两个文章之间跳转 但是并没有访问 /s?_biz 这类链接

    猜测视频是用 iframe 嵌入的 因为如果把视频链接修改到别的地址的话(如百度) 播放器位置会显示相应结果 而不是整个文章页面变成百度

    不确定是不是我改出问题了……

    我改成了从 mysql 读文章地址再去控制客户端访问的形式
    lijinma
        52
    lijinma  
    OP
       2017-04-08 10:46:30 +08:00
    @MrFireAwayH 我也遇到过,还没找到原因,循环的时候,刷新一下就可以继续下去,你能帮忙改改代码吗?

    这两天有点忙。
    MrFireAwayH
        53
    MrFireAwayH  
       2017-04-10 01:10:04 +08:00
    @lijinma #52 我这两天根据你的思路 自己撸了个工具出来 在 https://www.v2ex.com/t/352758

    至于这个无限循环的问题,我觉得可能是微信的内置浏览器有问题,至于你说的刷新一下就解决了,是因为刷新后会重新访问 /s?_biz 链接

    我目前采用了计数器的方式解决,初始化时候 FindAll 计算总数 count ,再对其翻倍处理(因为每次访问一个文章,都需会有相对固定次数的多个请求),设置 index=0 ,每个 else if 下面则 index+=1 ,在最终的 else 那边做判断,如果翻倍后的 count 小于 index ,说明进去死循环了,则强制重启。

    上述办法不是很完美,还没找到更好的办法。。。
    MrFireAwayH
        54
    MrFireAwayH  
       2017-04-10 01:11:10 +08:00
    @MrFireAwayH #53 额 错了 地址是 https://www.v2ex.com/t/353684
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5129 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 67ms · UTC 01:17 · PVG 09:17 · LAX 17:17 · JFK 20:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.