上周一直在出差看论文和yy方法论,没有动手写代码。周五的时候需要在网上爬大量的文件,想着写个爬虫。但是手愈是不动愈是懒,抓了包发现网站是个明显设置了反爬虫的好网站之后,懒癌发作的我在借助现成的爬虫工具和自己亲自写之间拼命摇摆。嗯,最终还是懒得动手小姐获胜。
事实证明,懒,是没有好下场的
七七使用的现成爬虫工具是集搜客,据说很好用的爬虫工具。使用体会是,如果有代码基础的话还是自己手写吧,这个工具提供的简单的功能其实写几行代码就能实现。复杂的功能的话,嗯,搞懂工具怎么用大概跟自己写一个用的时间也差不多。最可怕的是,七七用一个周末的时间,搞懂了集搜客的连续动作、模拟点击这些复杂功能到底怎么实现,然后用实践证明,我要的功能这些复杂模式并不能起到作用。论坛里讲到大概集搜客的飞掠模式可以达到七七想要的效果,但素七七没有经费购买飞掠模式。于是还是得自己动手,丰衣足食。
这个好网站反爬虫主要体现在两个方面,一个是点击download抓包到的目标网址是不能直接get到的,一个是频繁点击的时候会被直接封号。
第一个问题是最困扰我的问题,用简单的urllib2.get失败之后思路直接走偏。一开始想借用集搜客的连续动作和模拟点击功能,直接模拟点击download按钮,把网站里的文件点点点下载下来。后来发现集搜客搞不动之后,又想调用Python的selenium库直接做网页模拟点击。然而,这个定位还是比较愚蠢的,点错地方了就容易陷入死循环。这两个方法其实是逃避直接接触http协议想到的偷懒方式,偷懒失败后,只能回归http通信,然后发现,用通信的方式好简单。
只要能够完全的模拟报头,就能完美起到点击的作用。这里不得不提,firefox作为一款业余抓包工具真的很好用,通过分析点击的时候发送的request header,可以发现报头的规律,人为模拟这个规律,就可以达到点击的效果。具体到这个好网站,我完整的模拟了发送的报头,用控制变量的方法发现,cookie的使用是极为关键的。同时为了防止自己的账户被禁,cookie的模拟变换以及适当的抓取间隔设置是必要的。
(查看发送request之后response的报头与网页实际点击之后response的报头是不是一样,看看自己模拟的哪里有问题)
实践用教训告诉我们,偷懒米有好结果,不到半天的工作量生生耗进去了一个周末加半天。
途中发现了一个很好用的firefox的插件,名字叫做,downthemall,可以批量下载网站的文件,还可以设置规则跨网页下载,如果大学的时候发现了这个神器,一定把网络学堂的课件全珍藏下来,推荐推荐。
放源代码吧
import urllib2
import urllib
import requests
import sys
import random
import time
#sys.setdefaultencoding('utf-8')
def get_rep(url_p, vid, cnsuser_id, cnscc, _ym_uid, role):
filname = role+'_'+url_p.split('/')[-2]+'.rep'
cookie_str = 'vid='+vid+',cnsuser_id='+cnsuser_id+', cnscc='+cnscc+', _ym_uid='+_ym_uid+', _ym_isad=2'
header = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/54.0',
'Accept-Encoding':'gzip, deflate',
'Referer':'####', #your url
'Host':'###', #your url host
'Connection':'keep-alive',
'Accept-Language':'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Cookie':cookie_str}
reurl = url_p
req = urllib2.Request(url = reurl)
out = open(filename,'w')
r = requests.get(url = reurl, headers=header,stream=True)
#print r.content
#print r.headers
out.write(r.content)
out.close()
def generate_cookie():
base_vid = 14000
base_cnsuser_id = 2500000196
base_cnscc = 1495000019
base_ym_uid = 149551000007843736
vid_random_index = random.randint(1,4)
cnsuser_random_index = random.randint(1,9)
cnscc_random_index = random.randint(1,9)
uid_random_index = random.randint(1,17)
change = random.randint(0,9)
print vid_random_index, cnsuser_random_index, cnscc_random_index, uid_random_index,change
vid_old_index = int(str(base_vid)[vid_random_index])
vid_new = base_vid -(vid_old_index-change) *pow(10,4-vid_random_index)
cnsuser_old_index = int(str(base_cnsuser_id)[cnsuser_random_index])
cnsuser_id_new = base_cnsuser_id -(cnsuser_old_index-change) *pow(10,9-cnsuser_random_index)
cnscc_old_index = int(str(base_cnscc)[cnscc_random_index])
cnscc_new = base_cnscc-(cnscc_old_index-change)*pow(10,9-cnscc_random_index)
uid_old_index = int(str(base_ym_uid)[uid_random_index])
ym_uid_new = base_ym_uid-(uid_old_index-change)*pow(10,17-uid_random_index)
print vid_new, cnsuser_id_new, cnscc_new, ym_uid_new
return vid_new, cnsuser_id_new, cnscc_new, ym_uid_new
if __name__=="__main__":
dir = 'D:/ол┐кн║/url_list'
files = ['pvp','zvz','tvt','tvz','pvt','pvz']
for file_name in files:
role = file_name
file_path = dir + file_name
with open(file_path) as f:
for each_link in f:
each_link = each_link.strip('\n')
vid_new, cnsuser_id_new, cnscc_new, ym_uid_new = generate_cookie()
get_rep(each_link, vid_new, cnsuser_id_new, cnscc_new, ym_uid_new, role)
time.sleep(1)