python 爬虫:百度网盘爬虫(资源校验问题求大神交流) - V2EX
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
3023369823
V2EX    Python

python 爬虫:百度网盘爬虫(资源校验问题求大神交流)

  •  
  •   3023369823 2016-08-23 12:04:26 +08:00 5035 次点击
    这是一个创建于 3389 天前的主题,其中的信息可能已经有所发展或是发生改变。

    因为要做去转盘网分类模式点我),所以一定要爬取网盘资源,本来想自己写一个爬虫挺不容易的,不想分享出来,但最后还是决定了拿给大家一起看吧,毕竟有交流才有进步,有兴趣的朋友也可以看看我写的其他日志或者关注我,会发现去转盘网的大部分技术现在可以说是公开状态,如有对你有帮助还是认真读读吧,下面是爬虫代码,我立马公开:

    ps :不会 python 的孩子先去学学 python ,代码是 python 写的

    我附上点资料:点我下载 1 点我下载 2

    磁力站的源码我也公开了,放到了下面,喜欢的看看:ok 搜搜

    TEL :继本篇之后,以下是其他所有重要的博客,喜欢的可以看看:

    中文分词算法 邀请好友注册 js 分页部分代码 数据库备份 ok 搜搜爬虫源代码

    #coding: utf8 """ author:haoning create time: 2015-8-15 """ import re #正则表达式模块 import urllib2 #获取 URLs 的组件 import time from Queue import Queue import threading, errno, datetime import json import requests #Requests is an Apache2 Licensed HTTP library import MySQLdb as mdb DB_HOST = '127.0.0.1' DB_USER = 'root' DB_PASS = '' #以下是正则匹配规则 re_start = re.compile(r'start=(\d+)') #\d 表示 0-9 任意一个数字 后面有+号 说明这个 0-9 单个数位出现一到多次 比如 21312314 re_uid = re.compile(r'query_uk=(\d+)') #查询编号 re_urlid = re.compile(r'&urlid=(\d+)') #url 编号 OnEPAGE= 20 #一页数据量 OnESHAREPAGE= 20 #一页分享连接量 #缺少专辑列表 URL_SHARE = 'http://yun.baidu.com/pcloud/feed/getsharelist?auth_type=1&start={start}&limit=20&query_uk={uk}&urlid={id}' #获得分享列表 """ {"feed_type":"share","category":6,"public":"1","shareid":"1541924625","data_id":"2418757107690953697","title":"\u5723\u8bde\u58c1\u7eb8\u5927\u6d3e\u9001","third":0,"clienttype":0,"filecount":1,"uk":1798788396,"username":"SONYcity03","feed_time":1418986714000,"desc":"","avatar_url":"http:\/\/himg.bdimg.com\/sys\/portrait\/item\/1b6bf333.jpg","dir_cnt":1,"filelist":[{"server_filename":"\u5723\u8bde\u58c1\u7eb8\u5927\u6d3e\u9001","category":6,"isdir":1,"size":1024,"fs_id":870907642649299,"path":"%2F%E5%9C%A3%E8%AF%9E%E5%A3%81%E7%BA%B8%E5%A4%A7%E6%B4%BE%E9%80%81","md5":"0","sign":"1221d7d56438970225926ad552423ff6a5d3dd33","time_stamp":1439542024}],"source_uid":"871590683","source_id":"1541924625","shorturl":"1dDndV6T","vCnt":34296,"dCnt":7527,"tCnt":5056,"like_status":0,"like_count":60,"comment_count":19}, public:公开分享 title:文件名称 uk:用户编号 """ URL_FOLLOW = 'http://yun.baidu.com/pcloud/friend/getfollowlist?query_uk={uk}&limit=20&start={start}&urlid={id}' #获得订阅列表 """ {"type":-1,"follow_uname":"\u597d\u55e8\u597d\u55e8\u554a","avatar_url":"http:\/\/himg.bdimg.com\/sys\/portrait\/item\/979b832f.jpg","intro":"\u9700\u8981\u597d\u8d44\u6599\u52a0994798392","user_type":0,"is_vip":0,"follow_count":2,"fans_count":2276,"follow_time":1415614418,"pubshare_count":36,"follow_uk":2603342172,"album_count":0}, follow_uname:订阅名称 fans_count :粉丝数 """ URL_FANS = 'http://yun.baidu.com/pcloud/friend/getfanslist?query_uk={uk}&limit=20&start={start}&urlid={id}' # 获取关注列表 """ {"type":-1,"fans_uname":"\u62e8\u52a8\u795e\u7684\u5fc3\u7eea","avatar_url":"http:\/\/himg.bdimg.com\/sys\/portrait\/item\/d5119a2b.jpg","intro":"","user_type":0,"is_vip":0,"follow_count":8,"fans_count":39,"follow_time":1439541512,"pubshare_count":15,"fans_uk":288332613,"album_count":0} avatar_url :头像 fans_uname :用户名 """ QNUM = 1000 hc_q = Queue(20) #请求队列 hc_r = Queue(QNUM) #接收队列 success = 0 failed = 0 def req_worker(inx): #请求 s = requests.Session() #请求对象 while True: req_item = hc_q.get() #获得请求项 req_type = req_item[0] #请求类型,分享?订阅?粉丝? url = req_item[1] #url r = s.get(url) #通过 url 获得数据 hc_r.put((r.text, url)) #将获得数据文本和 url 放入接收队列 print "req_worker#", inx, url #inx 线程编号; url 分析了的 url def response_worker(): #处理工作 dbcOnn= mdb.connect(DB_HOST, DB_USER, DB_PASS, 'baiduyun', charset='utf8') dbcurr = dbconn.cursor() dbcurr.execute('SET NAMES utf8') dbcurr.excute('set global wait_timeout=60000') #以上皆是数据库操作 while True: """ #正则备注 match() 决定 RE 是否在字符串刚开始的位置匹配 search() 扫描字符串,找到这个 RE 匹配的位置 findall() 找到 RE 匹配的所有子串,并把它们作为一个列表返回 finditer() 找到 RE 匹配的所有子串,并把它们作为一个迭代器返回 百度页面链接: http://pan.baidu.com/share/link?shareid=3685432306&uk=1798788396&from=hotrec uk 其实用户 id 值 """ metadata, effective_url = hc_r.get() #获得 metadata (也就是前面的 r.text )和有效的 url #print "response_worker:", effective_url try: tnow = int(time.time()) #获得当前时间 id = re_urlid.findall(effective_url)[0] #获得 re_urlid 用户编号 start = re_start.findall(effective_url)[0] #获得 start 用户编号 if True: if 'getfollowlist' in effective_url: #type = 1 ,也就是订阅类 follows = json.loads(metadata) #以将文本数据转化成 json 数据格式返回 uid = re_uid.findall(effective_url)[0] #获得 re_uid ,查询编号 if "total_count" in follows.keys() and follows["total_count"]>0 and str(start) == "0": #获得订阅数量 for i in range((follows["total_count"]-1)/ONEPAGE): #开始一页一页获取有用信息 try: dbcurr.execute('INSERT INTO urlids(uk, start, limited, type, status) VALUES(%s, %s, %s, 1, 0)' % (uid, str(ONEPAGE*(i+1)), str(ONEPAGE))) #存储 url 编号,订阅中有用户编号, start 表示从多少条数据开始获取,初始 status=0 为未分析状态 except Exception as ex: print "E1", str(ex) pass if "follow_list" in follows.keys(): #如果订阅者也订阅了,即拥有 follow_list for item in follows["follow_list"]: try: dbcurr.execute('INSERT INTO user(userid, username, files, status, downloaded, lastaccess) VALUES(%s, "%s", 0, 0, 0, %s)' % (item['follow_uk'], item['follow_uname'], str(tnow))) #存储订阅这的用户编号,用户名,入库时间 except Exception as ex: print "E13", str(ex) pass else: print "delete 1", uid, start dbcurr.execute('delete from urlids where uk=%s and type=1 and start>%s' % (uid, start)) elif 'getfanslist' in effective_url: #type = 2,也就是粉丝列表 fans = json.loads(metadata) uid = re_uid.findall(effective_url)[0] if "total_count" in fans.keys() and fans["total_count"]>0 and str(start) == "0": for i in range((fans["total_count"]-1)/ONEPAGE): try: dbcurr.execute('INSERT INTO urlids(uk, start, limited, type, status) VALUES(%s, %s, %s, 2, 0)' % (uid, str(ONEPAGE*(i+1)), str(ONEPAGE))) except Exception as ex: print "E2", str(ex) pass if "fans_list" in fans.keys(): for item in fans["fans_list"]: try: dbcurr.execute('INSERT INTO user(userid, username, files, status, downloaded, lastaccess) VALUES(%s, "%s", 0, 0, 0, %s)' % (item['fans_uk'], item['fans_uname'], str(tnow))) except Exception as ex: print "E23", str(ex) pass else: print "delete 2", uid, start dbcurr.execute('delete from urlids where uk=%s and type=2 and start>%s' % (uid, start)) else: #type=0 ,也即是分享列表 shares = json.loads(metadata) uid = re_uid.findall(effective_url)[0] if "total_count" in shares.keys() and shares["total_count"]>0 and str(start) == "0": for i in range((shares["total_count"]-1)/ONESHAREPAGE): try: dbcurr.execute('INSERT INTO urlids(uk, start, limited, type, status) VALUES(%s, %s, %s, 0, 0)' % (uid, str(ONESHAREPAGE*(i+1)), str(ONESHAREPAGE))) except Exception as ex: print "E3", str(ex) pass if "records" in shares.keys(): for item in shares["records"]: try: dbcurr.execute('INSERT INTO share(userid, filename, shareid, status) VALUES(%s, "%s", %s, 0)' % (uid, item['title'], item['shareid'])) #item['title']恰好是文件名称 #返回的 json 信息: except Exception as ex: #print "E33", str(ex), item pass else: print "delete 0", uid, start dbcurr.execute('delete from urlids where uk=%s and type=0 and start>%s' % (uid, str(start))) dbcurr.execute('delete from urlids where id=%s' % (id, )) dbconn.commit() except Exception as ex: print "E5", str(ex), id dbcurr.close() dbconn.close() #关闭数据库 def worker(): global success, failed dbcOnn= mdb.connect(DB_HOST, DB_USER, DB_PASS, 'baiduyun', charset='utf8') dbcurr = dbconn.cursor() dbcurr.execute('SET NAMES utf8') dbcurr.execute('set global wait_timeout=60000') #以上是数据库相关设置 while True: #dbcurr.execute('select * from urlids where status=0 order by type limit 1') dbcurr.execute('select * from urlids where status=0 and type>0 limit 1') #type>0,为非分享列表 d = dbcurr.fetchall() #每次取出一条数据出来 #print d if d: #如果数据存在 id = d[0][0] #请求 url 编号 uk = d[0][1] #用户编号 start = d[0][2] limit = d[0][3] type = d[0][4] #哪种类型 dbcurr.execute('update urlids set status=1 where id=%s' % (str(id),)) #状态更新为 1 ,已经访问过了 url = "" if type == 0: #分享 url = URL_SHARE.format(uk=uk, start=start, id=id).encode('utf-8') #分享列表格式化 #query_uk uk 查询编号 #start #urlid id url 编号 elif type == 1: #订阅 url = URL_FOLLOW.format(uk=uk, start=start, id=id).encode('utf-8') #订阅列表格式化 elif type == 2: #粉丝 url = URL_FANS.format(uk=uk, start=start, id=id).encode('utf-8') #关注列表格式化 if url: hc_q.put((type, url)) #如果 url 存在,则放入请求队列, type 表示从哪里获得数据 #通过以上的 url 就可以获得相应情况下的数据的 json 数据格式,如分享信息的,订阅信息的,粉丝信息的 #print "processed", url else: #否则从订阅者或者粉丝的引出人中获得信息来存储,这个过程是爬虫树的下一层扩展 dbcurr.execute('select * from user where status=0 limit 1000') d = dbcurr.fetchall() if d: for item in d: try: dbcurr.execute('insert into urlids(uk, start, limited, type, status) values("%s", 0, %s, 0, 0)' % (item[1], str(ONESHAREPAGE))) #uk 查询号,其实是用户编号 #start 从第 1 条数据出发获取信息 # dbcurr.execute('insert into urlids(uk, start, limited, type, status) values("%s", 0, %s, 1, 0)' % (item[1], str(ONEPAGE))) dbcurr.execute('insert into urlids(uk, start, limited, type, status) values("%s", 0, %s, 2, 0)' % (item[1], str(ONEPAGE))) dbcurr.execute('update user set status=1 where userid=%s' % (item[1],)) #做个标志,该条数据已经访问过了 #跟新了分享,订阅,粉丝三部分数据 except Exception as ex: print "E6", str(ex) else: time.sleep(1) dbconn.commit() dbcurr.close() dbconn.close() def main(): print 'starting at:',now() for item in range(16): t = threading.Thread(target = req_worker, args = (item,)) t.setDaemon(True) t.start() #请求线程开启,共开启 16 个线程 s = threading.Thread(target = worker, args = ()) s.setDaemon(True) s.start() #worker 线程开启 response_worker() #response_worker 开始工作 print 'all Done at:', now() 

    特别求问:

    本人现在发现个问题,百度云的链接失效问题很难解决,比如:

    https://pan.baidu.com/share/link?uk=186824885&shareid=1531849562

    当向百度发送 http 请求的时候,开始是好的,但随着 http 请求的频率过快,百度开始限制 ip ,也就是资源校验开始失效,这个问题很让然头疼,希望 V2EX 上的大神能够给出宝贵建议或者可行见解,十分感谢。

    本人建个 qq 群,欢迎大家一起交流技术, 群号: 512245829 喜欢微博的朋友关注:转盘娱乐即可

    11 条回复    2016-08-24 18:11:34 +08:00
    3023369823
        1
    3023369823  
    OP
       2016-08-23 12:06:49 +08:00
    沙发归 lz ,急求最后 lz 提出的问题的解决方案:
    **特别求问:**

    本人现在发现个问题,百度云的链接失效问题很难解决,比如:

    https://pan.baidu.com/share/link?uk=186824885&shareid=1531849562

    当向百度发送 http 请求的时候,开始是好的,但随着 http 请求的频率过快,百度开始限制 ip ,也就是资源校验开始失效,这个问题很让然头疼,希望 V2EX 上的大神能够给出宝贵建议或者可行见解,十分感谢。
    firefox12
        2
    firefox12  
       2016-08-23 13:24:54 +08:00
    因为你解决的问题 是百度要干掉的东西。 一开始不禁止 是怕误伤普通用户,随着你请求资源越来越多,会有越来越多的限制,最后直接跳验证码都是有可能的,任何一家公司都会这么做。
    3023369823
        3
    3023369823  
    OP
       2016-08-23 15:05:14 +08:00
    @firefox12 有思路?
    Thoxvi
        4
    Thoxvi  
       2016-08-24 10:12:48 +08:00
    既然限制 IP ,那能不能使用分布式?
    bianchensz
        5
    bianchensz  
       2016-08-24 10:12:56 +08:00
    前端狗表示无能为力,帮顶
    3023369823
        6
    3023369823  
    OP
       2016-08-24 10:26:53 +08:00
    @bianchensz js 发送 http 请求要跨域,这个显然是不符合互联网规范的,实现不了
    3023369823
        7
    3023369823  
    OP
       2016-08-24 10:27:38 +08:00
    @Thoxvi 分布式的话理论是可行的,但是费用又是个问题
    liubo
        8
    liubo  
       2016-08-24 15:33:37 +08:00
    限制 ip ,可以考虑用代理。
    1 、自己扫常见代理端口,收集可用代理。这个不太推荐,我自己尝试过效率比较低下,还不如花点钱买服务....
    2 、收集网络上的免费代理,然后验证;
    3 、用付费的代理服务。跟免费的相对,一般会提供 api 支持,直接调调接口就能获取代理列表。这个可用性稍微好一点,不过也不算高,自己定时验证一下可用性就行了。
    4 、还有一些专门给爬虫做代理服务的,这个自己找吧.
    3023369823
        10
    3023369823  
    OP
       2016-08-24 18:11:17 +08:00
    @liubo 谢谢哈,我研究下
    3023369823
        11
    3023369823  
    OP
       2016-08-24 18:11:34 +08:00
    @holajamc 好的,谢谢你,我研究下
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     923 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 21:54 PVG 05:54 LAX 13:54 JFK 16:54
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86