• 请不要在回答技术问题时复制粘贴 AI 生成的内容
rv54ntjwfm3ug8
V2EX  ›  程序员

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

  •  
  •   rv54ntjwfm3ug8 · Apr 5, 2022 · 6207 views
    This topic created in 1506 days ago, the information mentioned may be changed or developed.

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

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

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

    TCP 有非阻塞模式,设置 fcntl(sock, F_SETFL, O_NONBLOCK);管他服务器什么时候响应,先把 IP 包发出去再说,并发就上去了。
    fishCatcher
        5
    fishCatcher  
       Apr 5, 2022 via iPhone
    go 协程应该恰好满足你的需求,不知道 python 和 c#实现的如何。
    或者固定一个 io 线程,剩下几个线程处理数据
    macrorules
        6
    macrorules  
       Apr 5, 2022
    C# + 宇宙第一 IDE 横扫一切
    Richard14
        7
    Richard14  
       Apr 5, 2022   ❤️ 1
    需求比较简单,哪个语言都无所谓。Python 的话,首先你需要调高系统允许最大 socket 连接数,创建 asyncio 线程,每个线程可以并发 1-10k 的访问,然后再将这个线程用 multiprocessing 重复。瓶颈只在于系统 IO ,与应用层实现关系不大
    vance123
        8
    vance123  
       Apr 5, 2022 via Android
    虽然没有并发限制,但服务器带宽还是有限的。假设每个文件 100k ,服务器带宽 100m ,每秒也就 1000 个文件
    mxT52CRuqR6o5
        9
    mxT52CRuqR6o5  
       Apr 5, 2022 via Android
    @theklf4 你这个是 io 密集的需求,语言本身不会成为性能瓶颈
    documentzhangx66
        10
    documentzhangx66  
       Apr 5, 2022
    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  
       Apr 5, 2022
    Python 有开源的 scrapy 你要的需求都有了,直接用不香吗。
    opengps
        12
    opengps  
       Apr 5, 2022
    当然是你怎么熟悉怎么来。
    如果你同时是两门语言的顶尖高手,那么你才有必要去在乎采用哪门语言更高效
    keepeye
        13
    keepeye  
       Apr 5, 2022
    python 有现成的 scrapy 爬虫框架,不想用可以自己用 aiohttp + asyncio.Queue
    ragnaroks
        14
    ragnaroks  
       Apr 5, 2022
    如果你的环境是 windows 的话,dotnet 性能更好,默认情况下就是并行完成端口
    yolee599
        15
    yolee599  
       Apr 5, 2022 via Android
    用 C# 比较好
    ychost
        16
    ychost  
       Apr 5, 2022
    爬虫 py 比较合适
    ly841000
        17
    ly841000  
       Apr 5, 2022   ❤️ 2
    @documentzhangx66 .......按你这说法,必须 c#啊,c#性能本身就比 python 高一个数量级,还可以直接调用任何 api, c 库。。。python 还要封装,哪个更方便还要说?
    idragonet
        18
    idragonet  
       Apr 5, 2022
    C#做过爬虫挺好的,不过是抓取几万个网页而已。
    seakingii
        19
    seakingii  
       Apr 5, 2022
    安全吗,注意法律问题....
    两都都可以实现任务,不过考虑到数量级,尽量用性能高一点的语言吧,所以推荐用 c#而不是 python
    ch2
        20
    ch2  
       Apr 5, 2022
    这两个都能胜任,最大的瓶颈是你的网卡有多少带宽以及对面网站会给你一个 ip 分多少带宽
    Dockerfile
        21
    Dockerfile  
       Apr 5, 2022
    @ly841000 肯定是 python 方便,就发网络请求调什么 c 库,没麻烦找麻烦么
    ly841000
        22
    ly841000  
       Apr 5, 2022
    @Jwyt 说得 c#没我网络库似的。。。。
    wzzzx
        23
    wzzzx  
       Apr 5, 2022
    大部分的业务场景,语言都不是瓶颈
    iyaozhen
        24
    iyaozhen  
       Apr 5, 2022
    都行,不是瓶颈。Python 性能差不是在 IO 上差
    Dockerfile
        25
    Dockerfile  
       Apr 5, 2022
    @ly841000 你自己说的 c 库啊。。
    fanxiao
        26
    fanxiao  
       Apr 5, 2022
    c# async await 模式,挺适合这种 IO 密集型任务
    wangritian
        27
    wangritian  
       Apr 5, 2022
    语言不重要,协程模型是关键,最适合这件事的我觉得是 go
    westoy
        28
    westoy  
       Apr 5, 2022
    @Richard14

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