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

Python 那位大神帮忙看一下 这段爬虫代码 跑一会儿就停了 没报错 也没提示就是不动了

  •  
  •   mojito · 2019-05-20 17:34:49 +08:00 · 8881 次点击
    这是一个创建于 2011 天前的主题,其中的信息可能已经有所发展或是发生改变。
        # -*- coding:utf-8 -*-
    
    # 声明:知乎上某个答主写的爬虫脚本,代码没有整理,自己重新整理排版了,已经调试并通过
    #      本人 Java 程序员,对 python 不熟,不过代码里面逻辑大概能看懂一些,这位答主的脚本是 python2 写的,
    #      我自己是 python3 的环境,所以有些细微的改动,目的是为了兼容 python3 可以正常运行
    #
    #      原始脚本地址: https://www.zhihu.com/question/297715922/answer/676693318
    #      如果觉得我冒犯了你的话,可以私信联系我,我删除。
    
    import re
    import requests
    import os
    import urllib.request
    import ssl
    
    from urllib.parse import urlsplit
    from os.path import basename
    
    # 全局禁用证书验证
    ssl._create_default_https_context = ssl._create_unverified_context
    
    headers = {
        'User-Agent': "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36",
        'Accept-Encoding': 'gzip, deflate'
    }
    
    
    def mkdir(path):
        if not os.path.exists(path):
            print('新建文件夹:', path)
            os.makedirs(path)
            return True
        else:
            print(u"图片存放于:", os.getcwd() + os.sep + path)
            return False
    
    
    def download_pic2(img_lists, dir_name):
        print("一共有{num}张照片".format(num=len(img_lists)))
    
        # 标记下载进度
        index = 1
    
        for image_url in img_lists:
            file_name = dir_name + os.sep + basename(urlsplit(image_url)[2])
    
            # 已经下载的文件跳过
            if os.path.exists(file_name):
                print("文件{file_name}已存在。".format(file_name=file_name))
                index += 1
                continue
    
            auto_download(image_url, file_name)
    
            print("下载{pic_name}完成!({index}/{sum})".format(pic_name=file_name, index=index, sum=len(img_lists)))
            index += 1
    
    
    def auto_download(url, file_name):
        # 递归下载,直到文件下载成功
        try:
            urllib.request.urlretrieve(url, file_name)
        except urllib.request.ContentTooShortError:
            print("文件下载不完整,重新下载。")
            auto_download(url, file_name)
        except urllib.request.URLError:
            print("网络连接出错,尝试重新下载。")
            auto_download(url, file_name)
    
    
    def download_pic(img_lists, dir_name):
        print("一共有{num}张照片".format(num=len(img_lists)))
        for image_url in img_lists:
            response = requests.get(image_url, stream=True)
            if response.status_code == 200:
                image = response.content
            else:
                continue
    
            file_name = dir_name + os.sep + basename(urlsplit(image_url)[2])
    
            try:
                with open(file_name, "wb") as picture:
                    picture.write(image)
            except IOError:
                print("IO Error\n")
                continue
            finally:
                picture.close()
    
            print("下载{pic_name}完成!".format(pic_name=file_name))
    
    
    def get_image_url(qid, headers):
        # 利用正则表达式把源代码中的图片地址过滤出来
        # reg = r'data-actualsrc="(.*?)">'
        tmp_url = "https://www.zhihu.com/node/QuestionAnswerListV2"
        size = 10
        image_urls = []
    
        session = requests.Session()
    
        while True:
            postdata = {'method': 'next',
                        'params': '{"url_token":' + str(qid) + ',"pagesize": "10",' + '"offset":' + str(size) + "}"}
            page = session.post(tmp_url, headers=headers, data=postdata)
            ret = eval(page.text)
            answers = ret['msg']
            print(u"答案数:%d" % (len(answers)))
    
            size += 10
    
            if not answers:
                print("图片 URL 获取完毕, 页数: ", (size - 10) / 10)
                return image_urls
    
            # reg = r'https://pic\d.zhimg.com/[a-fA-F0-9]{5,32}_\w+.jpg'
            imgreg = re.compile('data-original="(.*?)"', re.S)
    
            for answer in answers:
                tmp_list = []
                url_items = re.findall(imgreg, answer)
    
                for item in url_items:  # 这里去掉得到的图片 URL 中的转义字符'\\'
                    image_url = item.replace("\\", "")
                    tmp_list.append(image_url)
    
                # 清理掉头像和去重 获取 data-original 的内容
                tmp_list = list(set(tmp_list))  # 去重
                for item in tmp_list:
                    if item.endswith('r.jpg'):
                        print(item)
                        image_urls.append(item)
    
            print('size: %d, num : %d' % (size, len(image_urls)))
    
    
    if __name__ == '__main__':
        title = '拥有一副令人羡慕的好身材是怎样的体验?'
        question_id = 297715922
    
        # title = '身材好是一种怎样的体验?'
        # question_id = 26037846
    
        # title = '女孩子胸大是什么体验?'
        # question_id = 291678281
    
        # title = '女生什么样的腿是美腿?'
        # question_id = 310786985
    
        # title = '你的择偶标准是怎样的?'
        # question_id = 275359100
    
        # title = '什么样才叫好看的腿?'
        # question_id = 63727821
    
        # title = '身材对女生很重要吗?'
        # question_id = 307403214
    
        # title = '女生腿长是什么样的体验?'
        # question_id = 273711203
    
        # title = '女生腕线过裆是怎样一种体验?'
        # question_id = 315236887
    
        # title = '有着一双大长腿是什么感觉?'
        # question_id = 292901966
    
        # title = '拥有一双大长腿是怎样的体验?'
        # question_id = 285321190
    
        # title = '大胸女生如何穿衣搭配?'
        # question_id = 26297181
    
        # title = '胸大到底怎么穿衣服好看?'
        # question_id = 293482116
    
        zhihu_url = "https://www.zhihu.com/question/{qid}".format(qid=question_id)
        path = str(question_id) + '_' + title
        mkdir(path)  # 创建本地文件夹
        img_list = get_image_url(question_id, headers)  # 获取图片的地址列表
        download_pic2(img_list, path)  # 保存图片
    
    91 条回复    2019-05-22 15:45:51 +08:00
    libaibuaidufu
        1
    libaibuaidufu  
       2019-05-20 17:59:43 +08:00
    可以运行 图片不错哦 是不是环境没有配对
    xabc
        2
    xabc  
       2019-05-20 18:02:18 +08:00
    原谅我 ,我笑了 😊
    Ultraman
        3
    Ultraman  
       2019-05-20 18:02:35 +08:00 via Android
    1024
    Outliver0
        4
    Outliver0  
       2019-05-20 18:03:13 +08:00
    能跑,我直接复制的代码,图片可以的
    libaibuaidufu
        5
    libaibuaidufu  
       2019-05-20 18:03:27 +08:00
    第一个就 3000 张图片 知乎会不会把我 ip 限制了
    Outliver0
        6
    Outliver0  
       2019-05-20 18:15:15 +08:00
    我下了六百多,关了,怕被封
    zhze93
        7
    zhze93  
       2019-05-20 18:17:53 +08:00
    我佛了
    jdgui
        8
    jdgui  
       2019-05-20 18:22:12 +08:00
    我怀疑你是来开车的,但是我没有证据
    CSM
        9
    CSM  
       2019-05-20 18:55:16 +08:00 via Android
    感谢分享,楼主好人一生平安
    kkjinping
        10
    kkjinping  
       2019-05-20 19:03:20 +08:00
    这是啥,是车吗
    j4fun
        11
    j4fun  
       2019-05-20 19:06:06 +08:00
    我怀疑你是来开车的,但是我没有证据
    Raynard
        12
    Raynard  
       2019-05-20 19:09:06 +08:00
    楼主你好,楼主再见
    lonelygo
        13
    lonelygo  
       2019-05-20 19:27:56 +08:00
    疑车无据
    Eiden
        14
    Eiden  
       2019-05-20 19:33:24 +08:00 via Android
    不多说了,感谢楼主
    fuchunliu
        15
    fuchunliu  
       2019-05-20 21:22:30 +08:00 via Android
    看了评论,赶紧打开电脑跑一下是啥图片😏
    xloong
        16
    xloong  
       2019-05-20 21:33:25 +08:00 via iPhone
    给 requests 等网络请求增加超时限制
    Takamine
        17
    Takamine  
       2019-05-20 21:33:34 +08:00
    楼主放我出去,这不是去幼儿园的车!!!
    wfd0807
        18
    wfd0807  
       2019-05-20 21:42:06 +08:00
    设置超时时间,以前遇到过,requests 默认超时不报错,会一直等下去
    hmxxmh
        19
    hmxxmh  
       2019-05-20 21:44:03 +08:00   ❤️ 1
    谢谢,是你带我走上了爬虫的道路
    hasoidhaio
        20
    hasoidhaio  
       2019-05-20 21:48:29 +08:00
    好人一生平安 xd
    purgle
        21
    purgle  
       2019-05-20 22:31:13 +08:00 via Android
    一般是请求读超时阻塞了,对于外部请求,最好把 connect timeout 和 read timeout 都加上
    stzz
        22
    stzz  
       2019-05-20 23:07:37 +08:00   ❤️ 4
    本人 Python 也不熟,但看到代码里的中文,我觉得我可以熟
    dingyaguang117
        23
    dingyaguang117  
       2019-05-20 23:16:14 +08:00
    不用看内容就知道是 socket 超时没设置
    Zakl21
        24
    Zakl21  
       2019-05-21 00:42:12 +08:00 via Android
    我要试试了
    mrnull0
        25
    mrnull0  
       2019-05-21 01:02:48 +08:00
    看前面说的,可能是 socket 的坑,这个坑我遇到过,只能加上延时了
    sama666
        26
    sama666  
       2019-05-21 07:44:59 +08:00 via Android
    这不是开往秋名山的车,放我下来
    xwcs
        27
    xwcs  
       2019-05-21 08:01:33 +08:00 via Android
    我怀疑你在开车但是我没有证据,请求超时了吧
    zw1027
        28
    zw1027  
       2019-05-21 08:24:54 +08:00
    楼主好人一生平安
    wwg1994
        29
    wwg1994  
       2019-05-21 08:27:26 +08:00
    我怀疑你在开车,并且证据确凿(俺硬盘都满了!)
    d0m2o08
        30
    d0m2o08  
       2019-05-21 08:32:44 +08:00
    立即靠边停车,接受检查!
    dreamusername
        31
    dreamusername  
       2019-05-21 08:58:49 +08:00
    龟龟如何提高 python 爬虫水平
    mojito
        32
    mojito  
    OP
       2019-05-21 09:01:41 +08:00
    @libaibuaidufu 我的也能跑 但是下到 50 多张的时候就停了 没反应!
    mojito
        33
    mojito  
    OP
       2019-05-21 09:02:18 +08:00
    @Outliver0 我才能下 60 多张 然后就不动了!
    mojito
        34
    mojito  
    OP
       2019-05-21 09:04:36 +08:00
    @xloong 具体怎么加呢?指导一下!谢谢!
    keepeye
        35
    keepeye  
       2019-05-21 09:04:41 +08:00
    这么漂亮的屁股,答应我别用来拉屎好吗? 233333
    Outliver0
        36
    Outliver0  
       2019-05-21 09:21:10 +08:00
    @mojito 我什么都没干,就运行一下代码,估计你被限制了
    JimmyTinsley
        37
    JimmyTinsley  
       2019-05-21 09:21:30 +08:00   ❤️ 1
    以前还用过 tumblr 一键拉图的脚本, 那个更伤身体[滑稽]
    libaibuaidufu
        38
    libaibuaidufu  
       2019-05-21 09:25:33 +08:00   ❤️ 1
    @mojito 我 3000 多张都下载完了。。。。。 是不是你测试很多次 然后被封了 还能看知乎吗。。。
    tikazyq
        39
    tikazyq  
       2019-05-21 09:33:29 +08:00
    不管是不是开车,爬友们可以关注下爬虫平台 crawlab,更方便的管理你的爬虫,https://github.com/tikazyq/crawlab
    coeo91
        40
    coeo91  
       2019-05-21 09:33:47 +08:00 via iPhone
    我桌面上莫名出现新建文件夹是不是有爬虫来过?
    ervqq
        41
    ervqq  
       2019-05-21 09:44:40 +08:00
    代码车。。。。
    mojito
        42
    mojito  
    OP
       2019-05-21 10:12:57 +08:00
    @libaibuaidufu 还能看
    xloong
        43
    xloong  
       2019-05-21 10:21:14 +08:00 via iPhone
    @mojito 搜一下 requests timeout
    gimp
        44
    gimp  
       2019-05-21 10:30:09 +08:00
    我怀疑你在开车,并且电脑里已经保存了证据!
    aaa5838769
        45
    aaa5838769  
       2019-05-21 10:34:54 +08:00
    楼主,你不用代理么,胆子这么大么= =
    CatTom
        46
    CatTom  
       2019-05-21 10:40:50 +08:00
    车门已焊死,谁都别想下
    https://s2.ax1x.com/2019/05/21/EzN6BR.png
    zhangpeter
        47
    zhangpeter  
       2019-05-21 10:42:17 +08:00
    上车了
    pytth
        48
    pytth  
       2019-05-21 10:56:41 +08:00
    感觉是好东西。

    ![微信图片_20190521105602.png]( https://i.loli.net/2019/05/21/5ce368d753edb20750.png)
    xiaohuangya
        49
    xiaohuangya  
       2019-05-21 11:23:39 +08:00
    我可以下载完成一个问题的图片,没有卡住。
    Motoi
        50
    Motoi  
       2019-05-21 11:27:05 +08:00
    快让我下车
    karottc
        51
    karottc  
       2019-05-21 12:01:17 +08:00 via iPhone
    没问题。正常运行完成,一行没改。

    下载 297715922_拥有一副令人羡慕的好身材是怎样的体验?/v2-84eef01f7096b357aa0ae6f84aa65651_r.jpg 完成!(2974/2975)
    下载 297715922_拥有一副令人羡慕的好身材是怎样的体验?/v2-db77d7aebfea4516c2e05c06cbca9532_r.jpg 完成!(2975/2975)
    jakeyfly
        52
    jakeyfly  
       2019-05-21 15:16:13 +08:00
    @dingyaguang117 scoket 怎么加延迟啊
    TimPeake
        53
    TimPeake  
       2019-05-21 15:19:05 +08:00
    楼主好人一生平安
    usingnamespace
        54
    usingnamespace  
       2019-05-21 15:19:29 +08:00 via iPhone
    @dreamusername 爬虫真的是个简单玩意 大部分都跟好爬的 除了一些地狱难度的
    usingnamespace
        55
    usingnamespace  
       2019-05-21 15:21:22 +08:00 via iPhone
    @coeo91 别人怎么可能可以在你那儿建文件夹
    gosansam
        56
    gosansam  
       2019-05-21 15:24:03 +08:00
    稍等我安装一个 p3 的环境嗷
    lofbat
        57
    lofbat  
       2019-05-21 15:26:48 +08:00
    疑开车,无证据
    sola97
        58
    sola97  
       2019-05-21 15:47:58 +08:00
    这个下载不行,会卡住,存一下 url 然后 aria2c -i 即可
    gosansam
        60
    gosansam  
       2019-05-21 16:09:54 +08:00
    下载 297715922_拥有一副令人羡慕的好身材是怎样的体验?/v2-c12cfa89db2468492f195061f13c4420_r.jpg 完成!(2982/2982)
    onecode
        61
    onecode  
       2019-05-21 16:13:22 +08:00
    我决定写个.net core 的版本
    xdlucky
        62
    xdlucky  
       2019-05-21 16:15:33 +08:00
    下好的老哥能不能给个网盘, 我想看看爬虫的质量如何, 谢谢
    jxf2008
        63
    jxf2008  
       2019-05-21 16:16:50 +08:00
    ```c++
    while(0)
    {

    }
    ```
    楼主干脆把你的测试网站一起贴上来吧。。
    glaucus
        64
    glaucus  
       2019-05-21 16:17:29 +08:00
    LZ 好人,变相发福利
    aborigine
        65
    aborigine  
       2019-05-21 16:19:15 +08:00
    加了个循环已经跑到第四个问题了😂
    ETiV
        66
    ETiV  
       2019-05-21 16:21:33 +08:00 via iPhone
    ……

    希望 iCloud 剪切板可以保持到我拉完屎还能在电脑上粘贴
    registerrr
        67
    registerrr  
       2019-05-21 16:23:06 +08:00
    运行了一半我给它停住了,只建了个空文件夹没有下载?
    onecode
        68
    onecode  
       2019-05-21 16:24:01 +08:00
    那个,有没有搞个机器学习把跟主题无关的图片过滤掉呢
    ioschen
        69
    ioschen  
       2019-05-21 16:25:02 +08:00
    以前看过爬虫作者发的这个,
    你复制过来开车干嘛,开车痕迹太大😂

    -------------------------
    python2 用户

    改动 1
    import urllib
    #import urllib.request

    改动 2
    from urlparse import urlsplit
    #from urllib.parse import urlsplit

    做两处改动,然后所有的 urllib.request 改为 urllib
    wqzjk393
        70
    wqzjk393  
       2019-05-21 16:30:40 +08:00
    之前写的一个,只要 request 出错就暂停几秒钟然后随机更换 agent ip 之类的,继续做 request,直到成功才跳出循环。。用这个爬了笔趣阁好几本书。。。( https://s2.ax1x.com/2019/05/21/VSAF0A.png)
    onecode
        71
    onecode  
       2019-05-21 16:31:07 +08:00
    l0o0
        72
    l0o0  
       2019-05-21 16:33:35 +08:00
    我这边测试了之后达到了最大的循环数,就停止了
    fhsan
        73
    fhsan  
       2019-05-21 16:34:25 +08:00   ❤️ 1
    goodryb
        74
    goodryb  
       2019-05-21 16:44:24 +08:00
    代码没毛病,似乎知乎没有因为这种情况屏蔽 IP
    imyip
        75
    imyip  
       2019-05-21 16:51:54 +08:00
    刚好在写队列, 把 img_list 扔进队列,开启多线程下载
    danson1895
        76
    danson1895  
       2019-05-21 16:53:06 +08:00
    疑车无据
    SbloodyS
        77
    SbloodyS  
       2019-05-21 16:53:58 +08:00
    这个车。。。
    killerv
        78
    killerv  
       2019-05-21 16:56:32 +08:00
    我怀疑你在开车
    luolw1998
        79
    luolw1998  
       2019-05-21 16:56:59 +08:00
    图不错😍
    Rooney
        80
    Rooney  
       2019-05-21 17:01:37 +08:00
    楼主牛批,让我这个基本上不懂编程的非计算机专业的小白,在自己的摸索下第一次体验了爬虫的快乐,千言万语,不如一句先撸为精。
    skymei
        81
    skymei  
       2019-05-21 17:05:29 +08:00
    感谢楼主,已上车
    Immortal
        82
    Immortal  
       2019-05-21 17:15:05 +08:00
    加入收藏 从此走上爬虫路
    WantMarryGakki
        83
    WantMarryGakki  
       2019-05-21 17:20:21 +08:00
    等一个大神上传,分享链接
    wangfei324017
        84
    wangfei324017  
       2019-05-21 17:26:37 +08:00
    6ZO+5o6lOmh0dHBzOi8vcGFuLmJhaWR1LmNvbS9zLzFsa3lLWHFlc005SFpWSFlkVkFObU9nICDlr4bnoIE6bWJlaw==
    @WantMarryGakki #83
    @Immortal #82
    564425833
        85
    564425833  
       2019-05-21 17:32:16 +08:00
    #84 大佬已经给了
    a781305886
        86
    a781305886  
       2019-05-21 17:45:41 +08:00
    为了看福利 我踏马一个 php 跑去学了一下午的 py 终于跑起了
    siboom
        87
    siboom  
       2019-05-21 17:53:50 +08:00
    1024
    yuanyunguoyan
        88
    yuanyunguoyan  
       2019-05-21 17:56:11 +08:00
    成功运行,谢谢楼主
    hyy1995
        89
    hyy1995  
       2019-05-21 17:56:44 +08:00
    这个开车方式,很别致
    aa1072551507
        90
    aa1072551507  
       2019-05-22 12:07:35 +08:00
    很好,看到这 我觉得我前端要转爬虫了
    jzds001
        91
    jzds001  
       2019-05-22 15:45:51 +08:00
    😀
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1173 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 18:39 · PVG 02:39 · LAX 10:39 · JFK 13:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.