V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
yuban10703
V2EX  ›  Python

关于爬虫异步多线程的问题

  •  
  •   yuban10703 · 2020-05-31 12:59:31 +08:00 · 2771 次点击
    这是一个创建于 1637 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近一直在研究 py 的异步......

    所以想把之前整的一个 P 站收藏夹的爬虫换成异步,但是想了想,貌似收藏夹翻页的部分好像整不了异步?..

    爬虫代码

    (写的很乱.....😶)

    爬虫大概是这样运行的:

    1. 先登录获取用户信息
    2. 然后请求收藏夹的 api(这一步里会返回我收藏夹中第一页的信息和下一页的 url)
    3. 然后把上一步中第一页收藏夹的信息处理一下存进数据库
    4. 休眠一段时间后请求上一步中返回的 url(这里返回的信息和第二步一样,返回当前页的信息和下一页的 url)
    5. 然后处理信息存进数据库,一直循环第 4 步,直到下一页的 url 为 none

    返回的下一页的 url 貌似不固定,得从上一步的结果中取...,所以这步好像不能异步?...🤔

    但是数据库存储数据这步好像可以异步执行,但是怎么操作.......(创建了异步任务后需要 await 任务,await 任务这步貌似是堵塞的)😢

    不知道单用异步能不能解决这个问题...

    所以我想再开一个线程,把存数据库的操作丢到另一个线程里去操作...

    各位有什么想法么?.........还有 有关于 python asyncio 的教程推荐么..(中文的...)

    11 条回复    2020-06-01 15:49:23 +08:00
    ClericPy
        1
    ClericPy  
       2020-05-31 13:26:49 +08:00   ❤️ 1
    前几天刚看到的...
    Guide to Concurrency in Python with Asyncio ⋆ Mark McDonnell - https://www.integralist.co.uk/posts/python-asyncio/

    其他的搜索结果 https://www.clericpy.top/newspaper/articles.query.html?query=asyncio&date=&start_time=&end_time=&source=&lang=ANY&order_by=ts_create&sorting=desc&limit=10&offset= 只看四星以上结果吧, 这个过滤器当初忘了写... 过几天再补

    然后, asyncio 用的时候和多线程有点像, 但是又很多区别, 官方如果能设计的像 gevent 那种就好了... 不吐槽了, 大致要看的就是 Future 的思想, 然后知道 asyncio.Task 是一个已经在执行的协程任务, 如果你的数据库操作库不支持协程, 就只能丢到一个 "线程 executor" 里面做一个协程包装(也就是丢给线程, 但可以被 await)

    至于你说的从上一步结果里取, 那就是个串行关联了, 因为第二步可能也要用协程, 所以就尽量别用 add_done_callback, 做好 await 就行了

    多数人用协程的时候很少会开多个线程然它单独跑一个事件循环, 因为一不小心通信过程会遇到 different loop thread 之类的 runtime error, 所以用 executor 包装下更省心

    没代码也说不了太多了
    renmu123
        2
    renmu123  
       2020-05-31 13:37:13 +08:00 via Android
    你可以获取全部资料后一口气存到数据库,没必要获取一次存一次
    yuban10703
        3
    yuban10703  
    OP
       2020-05-31 13:40:39 +08:00
    @renmu123 emm, api 的请求之间有 5s 左右的间隔,主要是想利用这些时间....
    jugelizi
        4
    jugelizi  
       2020-05-31 14:07:46 +08:00
    哈哈 这种一般我丢任务队列
    一个任务去抓列表 存数据库 再推送队列
    另外一个不断消费
    yuban10703
        5
    yuban10703  
    OP
       2020-05-31 14:14:14 +08:00
    @jugelizi 我去研究研究🤔
    daimiaopeng
        6
    daimiaopeng  
       2020-05-31 15:59:08 +08:00
    我用 cpp 写的多线程 http 库可以了解一下: https://github.com/daimiaopeng/fast_requests
    yuban10703
        7
    yuban10703  
    OP
       2020-05-31 16:06:52 +08:00
    @daimiaopeng (☆▽☆)
    ruanimal
        8
    ruanimal  
       2020-05-31 17:27:34 +08:00
    你想异步需要换库,requests 得换成对应的异步库,还有数据库相关的库也是,不然异步没啥意义
    octobersnow
        9
    octobersnow  
       2020-05-31 21:58:31 +08:00 via Android
    @daimiaopeng 最快在哪里?
    black11black
        10
    black11black  
       2020-06-01 12:36:08 +08:00
    建议老实先看一遍庞杂的 aysncio 文档,了解一下异步大概是什么,你这些问的都哪跟哪啊
    coderunI
        11
    coderunI  
       2020-06-01 15:49:23 +08:00
    你需要 redis
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2717 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 12:17 · PVG 20:17 · LAX 04:17 · JFK 07:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.