V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
rv54ntjwfm3ug8
V2EX  ›  程序员

请求数百万个 URL, C#还是 Python 快且容易实现?

  •  
  •   rv54ntjwfm3ug8 · 2022-04-05 01:33:34 +08:00 · 5385 次点击
    这是一个创建于 945 天前的主题,其中的信息可能已经有所发展或是发生改变。

    场景是从一个 URL 获取数百万个任务(每次最多获取 1 万条任务,可自定义数量,但不能从中间开始获取,且每 2 秒只能请求一次任务列表),每个任务中的 URL 分别请求(访问每个 URL 需要 0.1~30+ 秒,目标网站没有并发限制),解析出需要的数据后上报需要的数据和任务 ID 到同一 URL (一次可以上报多个任务的结果)。因为不可能同时发几百万个请求,所以应该要用到线程池,设置最高同时多少任务在运行。请问这种场景的最佳实践是什么,C#还是 Python (我比较熟悉这两门语言)速度快且容易实现?

    39 条回复    2022-04-06 14:26:55 +08:00
    tulongtou
        1
    tulongtou  
       2022-04-05 01:44:43 +08:00 via iPhone
    这两门语言你都熟悉,为什么还需要问网友呢
    rv54ntjwfm3ug8
        2
    rv54ntjwfm3ug8  
    OP
       2022-04-05 01:45:53 +08:00
    @tulongtou #1 “比较熟悉”只是会用,不确定哪个在这种场景下性能高
    ZRS
        3
    ZRS  
       2022-04-05 01:48:07 +08:00   ❤️ 1
    瓶颈应该在网络 IO ,用啥语言问题都不大
    3dwelcome
        4
    3dwelcome  
       2022-04-05 01:48:18 +08:00   ❤️ 1
    我扫描过所有 ipv4 段的 80 端口服务,并发上限和开多少线程关系不大。

    影响 tcp 连接速度,主要因素是 DNS 的解析,TCP 的三次握手的等待时间。

    TCP 有非阻塞模式,设置 fcntl(sock, F_SETFL, O_NONBLOCK);管他服务器什么时候响应,先把 IP 包发出去再说,并发就上去了。
    fishCatcher
        5
    fishCatcher  
       2022-04-05 01:48:24 +08:00 via iPhone
    go 协程应该恰好满足你的需求,不知道 python 和 c#实现的如何。
    或者固定一个 io 线程,剩下几个线程处理数据
    macrorules
        6
    macrorules  
       2022-04-05 01:48:43 +08:00
    C# + 宇宙第一 IDE 横扫一切
    Richard14
        7
    Richard14  
       2022-04-05 01:50:40 +08:00   ❤️ 1
    需求比较简单,哪个语言都无所谓。Python 的话,首先你需要调高系统允许最大 socket 连接数,创建 asyncio 线程,每个线程可以并发 1-10k 的访问,然后再将这个线程用 multiprocessing 重复。瓶颈只在于系统 IO ,与应用层实现关系不大
    vance123
        8
    vance123  
       2022-04-05 01:59:28 +08:00 via Android
    虽然没有并发限制,但服务器带宽还是有限的。假设每个文件 100k ,服务器带宽 100m ,每秒也就 1000 个文件
    mxT52CRuqR6o5
        9
    mxT52CRuqR6o5  
       2022-04-05 04:57:25 +08:00 via Android
    @theklf4 你这个是 io 密集的需求,语言本身不会成为性能瓶颈
    documentzhangx66
        10
    documentzhangx66  
       2022-04-05 06:14:47 +08:00
    1.容易实现:Python ,原因是可直接白嫖的工具包,比 C#多的多。

    2.性能,也就是运行速度:不一定。虽然 C#性能比 Python 高得多,但 Python 可以直接调 C 库加持。

    3.稳定性:如果是公司要做正经的工程,并且是多人合作,那么 C#肯定比 Python 好。原因是 Python 语言缺少健壮性的支持,但这不是 Python 的错,胶水语言,比如 js ,都有这类问题。稳健需要强类型+强异常型语言。

    4.如果这需求,是我一个人来做,我会这样:

    先用 Python 做,但需要把功能分为不同模块。而且实现方法不能用 Python 的原生写法,而需要使用 Java 那一套工程化的结构模式。

    然后性能测试,哪个模块是性能瓶颈,用 C 库解决。如果是多人协作,甚至可以用 Redis 当中间库,Python 采集一手数据丢 Redis ,Cpp 从 Redis 拉取数据进行分析处理,并且 URL 的去重也用 Cpp 中间件做。
    Mutoo
        11
    Mutoo  
       2022-04-05 08:12:49 +08:00
    Python 有开源的 scrapy 你要的需求都有了,直接用不香吗。
    opengps
        12
    opengps  
       2022-04-05 09:11:02 +08:00
    当然是你怎么熟悉怎么来。
    如果你同时是两门语言的顶尖高手,那么你才有必要去在乎采用哪门语言更高效
    keepeye
        13
    keepeye  
       2022-04-05 09:57:58 +08:00
    python 有现成的 scrapy 爬虫框架,不想用可以自己用 aiohttp + asyncio.Queue
    ragnaroks
        14
    ragnaroks  
       2022-04-05 10:02:52 +08:00
    如果你的环境是 windows 的话,dotnet 性能更好,默认情况下就是并行完成端口
    yolee599
        15
    yolee599  
       2022-04-05 10:04:12 +08:00 via Android
    用 C# 比较好
    ychost
        16
    ychost  
       2022-04-05 10:18:44 +08:00
    爬虫 py 比较合适
    ly841000
        17
    ly841000  
       2022-04-05 11:39:45 +08:00   ❤️ 2
    @documentzhangx66 .......按你这说法,必须 c#啊,c#性能本身就比 python 高一个数量级,还可以直接调用任何 api, c 库。。。python 还要封装,哪个更方便还要说?
    idragonet
        18
    idragonet  
       2022-04-05 12:13:49 +08:00
    C#做过爬虫挺好的,不过是抓取几万个网页而已。
    seakingii
        19
    seakingii  
       2022-04-05 12:47:12 +08:00
    安全吗,注意法律问题....
    两都都可以实现任务,不过考虑到数量级,尽量用性能高一点的语言吧,所以推荐用 c#而不是 python
    ch2
        20
    ch2  
       2022-04-05 13:03:34 +08:00
    这两个都能胜任,最大的瓶颈是你的网卡有多少带宽以及对面网站会给你一个 ip 分多少带宽
    Jwyt
        21
    Jwyt  
       2022-04-05 13:05:01 +08:00
    @ly841000 肯定是 python 方便,就发网络请求调什么 c 库,没麻烦找麻烦么
    ly841000
        22
    ly841000  
       2022-04-05 13:41:16 +08:00
    @Jwyt 说得 c#没我网络库似的。。。。
    wzzzx
        23
    wzzzx  
       2022-04-05 14:06:58 +08:00
    大部分的业务场景,语言都不是瓶颈
    iyaozhen
        24
    iyaozhen  
       2022-04-05 14:21:55 +08:00
    都行,不是瓶颈。Python 性能差不是在 IO 上差
    Jwyt
        25
    Jwyt  
       2022-04-05 14:35:52 +08:00
    @ly841000 你自己说的 c 库啊。。
    fanxiao
        26
    fanxiao  
       2022-04-05 16:18:34 +08:00
    c# async await 模式,挺适合这种 IO 密集型任务
    wangritian
        27
    wangritian  
       2022-04-05 18:32:15 +08:00
    语言不重要,协程模型是关键,最适合这件事的我觉得是 go
    westoy
        28
    westoy  
       2022-04-05 18:37:58 +08:00
    @Richard14

    爬虫其实不需要多进程的,python 的 GIL 本来就不锁 IO, lxml 之类的配套基本也会释放 GIL 锁的......
    em70
        29
    em70  
       2022-04-05 18:47:23 +08:00
    哪个你写代码快用哪个
    Yunen
        30
    Yunen  
       2022-04-05 19:22:52 +08:00
    首选 golang
    ClericPy
        31
    ClericPy  
       2022-04-05 19:57:37 +08:00
    Python 请求几百万不是大量级, 带宽足够的情况下, aiohttp + uvloop 大约一小时以内就能搞定(之前爬 fb 380 万页请求开个多核加协程 50 分钟就抓完了), 如果是线程的话并发高了切换开销太大真不如协程, 性能损耗太大了. C# 不了解, 不过也算协程友好的, 熟悉哪个用哪个吧
    IvanLi127
        32
    IvanLi127  
       2022-04-05 22:53:02 +08:00 via Android
    我选 C#。
    ration
        33
    ration  
       2022-04-06 00:46:41 +08:00 via Android
    爬虫 python 的库多
    ElmerZhang
        34
    ElmerZhang  
       2022-04-06 10:13:28 +08:00
    我可能会选择写一段 shell
    Ackvincent
        35
    Ackvincent  
       2022-04-06 10:36:14 +08:00
    这不就是 python 的活嘛
    bthulu
        36
    bthulu  
       2022-04-06 10:42:47 +08:00
    要个屁的线程池啊, 单线程高宽带就行了. 把你这数百万个任务写到一个文件里, 然后直接下载这个文件就好了
    rv54ntjwfm3ug8
        37
    rv54ntjwfm3ug8  
    OP
       2022-04-06 12:01:30 +08:00
    @bthulu #36 有的 URL 不到 0.1 秒就请求完了,有的 URL 要等 10 分钟超时,显然爬的不可能是我的网站,有几个万个不同的网站
    bthulu
        38
    bthulu  
       2022-04-06 13:43:32 +08:00
    @theklf4 那就走异步, C#的异步 httpclient 很好用
    beyondex
        39
    beyondex  
       2022-04-06 14:26:55 +08:00
    当然是 C# 在并发、任务调度这块,官方、三方都用很好用的库
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2951 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 14:48 · PVG 22:48 · LAX 06:48 · JFK 09:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.