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
dbdoer
V2EX  ›  Python

抓取热点数据 mysql 该如何存取

  •  
  •   dbdoer · 2020-03-04 16:46:29 +08:00 · 3554 次点击
    这是一个创建于 1709 天前的主题,其中的信息可能已经有所发展或是发生改变。

    新手求教,刚学爬虫,想写个简单的抓新闻热点的练练手。

    在存入 mysql 时,每小时爬取一次,爬取完先 delete 表里的数据,再插入新的数据。

    如果想存下历史记录,会有个重复问题。这个时候该如何处理呢? 新建个历史表,每次插入最新的榜单之前,判断每条的标题是否历史库中已经存在,如果存在就将历史库中的删除。历史数据多了,不知道这个过程会不会很慢。。。

    想问下各位大哥,上面的想法是否正确,有没有更好的方式,谢谢

    27 条回复    2020-04-09 18:37:01 +08:00
    vitozyf
        1
    vitozyf  
       2020-03-04 17:50:24 +08:00
    不用 delete 吧,按热度设置一个 id,每次回来批量更新进去就行了
    kiracyan
        2
    kiracyan  
       2020-03-04 18:00:02 +08:00
    一个缓存表,爬的数据进这个表
    一个历史表,一个小时的时间随你怎么洗数据了
    shellus
        3
    shellus  
       2020-03-04 18:01:17 +08:00
    每个数据都有它的主键,例如你爬 https://www.v2ex.com/t/649832#reply1 这个帖子,那么它的主键就是 649832,你下次再爬到这个帖子的时候,就用 update 而不是 inster 就行了
    xkeyideal
        4
    xkeyideal  
       2020-03-04 18:09:18 +08:00
    用 mongodb,mysql 没有 upsert 原语,有时候不知道该 insert 还是 update,这涉及到并发
    Sanko
        5
    Sanko  
       2020-03-04 19:30:48 +08:00 via Android
    select for update
    lake325
        6
    lake325  
       2020-03-04 20:03:57 +08:00
    为什么要 delete 呢? 一直 insert 不好吗? select 的时候按照时间排序 limit 1
    wzwwzw
        7
    wzwwzw  
       2020-03-04 23:12:19 +08:00
    不 delete 直接 insert 记录好每次的时间。
    also24
        8
    also24  
       2020-03-04 23:26:01 +08:00
    说明你抓新闻的时候,只关注了新闻的标题和内容,没有关注那条新闻的其它数据。


    判断是否同一条新闻,未必要通过新闻标题内容,应当尽量使用其它更方便索引的信息来判断。

    例如:
    这个新闻是否有 id ?
    如果没有 id,是否有唯一的 url 参数?
    crella
        9
    crella  
       2020-03-05 09:03:18 +08:00 via Android
    数据量少的话,把所有 mysql 里面的数据读取到 python 里面,再在 python 的词典里修改,然后 mysql 删除表下所有内容,打开事务,写入到 mysql 表里。

    我大概 3000 多条招聘信息,目前没什么性能问题。
    crella
        10
    crella  
       2020-03-05 09:17:28 +08:00 via Android
    我那个用 sqlite3 数据库,而且希望整理数据的时间在十秒内。如果你对整理数据的速度要求不高的话,慢慢来就好,楼上几位大佬都有建议
    lostpupil
        11
    lostpupil  
       2020-03-05 09:41:41 +08:00
    如果是 帖子 ID,你还是需要帖子的来源,这两个放在一起才能避免 A 平台的 ID 和 B 平台 ID 重复的问题。
    如果存 历史数据,你在爬出来的时候可以对数据标题和内容进行摘要,把摘要值写进数据库去。
    回到第一条,不要用帖子 ID,标题作为主键,应该对于标题或者内容进行摘要,这样你既能快速的判断内容是否一致,也能方便的存储历史版本。
    CatTom
        12
    CatTom  
       2020-03-05 09:44:29 +08:00   ❤️ 1
    每一条新闻热点都会有一个独一的属性 ID,抓到这个属性后当做你的主键 ID 存数据库。然后不用 delete,MySQL 有一条很方便的 sql 可以让我们对数据操作时通过特定的属性来进行 insert 或 update。例:inerty into test(t1,t2,t3) value(t1,t2,t3) on duplicate key update t1 = values(t1)
    RangerWolf
        13
    RangerWolf  
       2020-03-05 09:45:35 +08:00
    楼上正解 ~ MySQL 非常好用的 feature 之一
    l3n641
        14
    l3n641  
       2020-03-05 10:00:06 +08:00
    热点放 redis 里面设置一个小时自动过期.然后历史库的数据只要保存历史的数据就可以了.
    luzihang
        15
    luzihang  
       2020-03-05 10:10:40 +08:00
    redis 用 set 去重。

    绝对去重,比如新闻更新:使用布隆过滤器或者 redis set
    标题+发布时间+更新时间计算一个 hash 值

    模糊去重,去除不同渠道互相抄袭的新闻:es 或者 simhash
    新闻标题+正文内容
    blessyou
        16
    blessyou  
       2020-03-05 10:16:59 +08:00
    @CatTom #12 学到了 谢谢
    luzihang
        17
    luzihang  
       2020-03-05 10:21:57 +08:00
    实际操作过 12 楼的方法,新闻正文这种长文本,各种转义,SQL 字符串拼接是个头疼的问题,没有成功过。
    dbdoer
        18
    dbdoer  
    OP
       2020-03-05 11:04:42 +08:00
    @shellus 感谢,之前确实只想着标题当主键。。。
    dbdoer
        19
    dbdoer  
    OP
       2020-03-05 11:06:21 +08:00
    @xkeyideal 谢谢,mongodb 还没来得及学,搞完 mysql 版回头对比一下
    dbdoer
        20
    dbdoer  
    OP
       2020-03-05 11:12:48 +08:00
    @lake325
    @wzwwzw
    谢谢,因为一开始想着简单,怕表里积累数据多了,每次 delete。。。
    dbdoer
        21
    dbdoer  
    OP
       2020-03-05 11:14:25 +08:00
    @also24 感谢,之前确实只盯着标题了,有了帖子 id 后面做比较就好多了
    dbdoer
        22
    dbdoer  
    OP
       2020-03-05 11:16:00 +08:00
    @crella 谢谢,学到了新思路,先在 python 里处理数据
    dbdoer
        23
    dbdoer  
    OP
       2020-03-05 11:18:12 +08:00
    @lostpupil 谢谢,学到了,对于标题或者内容进行 MD5 摘要
    dbdoer
        24
    dbdoer  
    OP
       2020-03-05 11:20:01 +08:00
    @CatTom 感谢,学到了
    dbdoer
        25
    dbdoer  
    OP
       2020-03-05 11:31:55 +08:00
    @l3n641 谢谢,记上 redis
    hushao
        26
    hushao  
       2020-04-09 18:35:54 +08:00
    如果保留历史记录,那么就只需要插入而不需要删除 /更新,取出的时候按照时间戳取最新结果就行。

    如果需要按标题判断,可以直接按标题建 unique key,然后 insert into on duplicate update...,另外标题可以做 md5 之类优化。

    另外 sqlite 直接可以 insert or update 吧。
    hushao
        27
    hushao  
       2020-04-09 18:37:01 +08:00
    。。。没看完回复,发现有人说过了,不好意思😂
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4890 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 05:40 · PVG 13:40 · LAX 21:40 · JFK 00:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.