Python爬虫

本来是准备爬取相亲网站的信息为广大单身青年做贡献的,但是注册虚假信息不太好,所以还是来爬取教程上的网站。

在装好python环境以及插件的情况下,在dos命令窗口输入“jupyter notebook" 命令,默认浏览器上会弹出如下窗口 :

选择 "New" 下的 "Python3" 选项,就会弹出一个新的编辑页面,接着就可以开始爬取图片信息了。

这次爬取的网站的URL为 : http://jandan.net/

第一页图片的URL : http://jandan.net/ooxx/page-1

第二页图片的URL : http://jandan.net/ooxx/page-2

类推最后一页图片的URL : http://jandan.net/ooxx/page-87

在每次访问http://jandan.net/ooxx/时,页面会自动锁定在最后一页,所以可以直接抓取这个页面的信息来获得网站类似页面的最大页数首先来抓取网页的源码 :


添加headers是为模拟网页登陆,避免一些反爬虫网站的拒绝请求,print(res.text)为打印网页源码(测试是否抓取到网页,后期删除),代码编辑完成后,点击shift + enter即可看到网页源码

返回需要抓取信息的网站,按F12进入开发者模式,找到最后一页87所在的标签



然后从span标签下抓取当前时间的最大页数 :

注 : 在获取最大页面的时候,代码获取到的数字带有 "[]" ,所以需要用切片来获取数字

得到最大的页面数后,开始循环所有页面


循环页面后,开始抓取各个页面的图片。首先在原网页的开发者模式下找到图片的标签 :


然后开始提取img的信息,通过img下的信息来访问图片 :


但是运行后的结果显示 :


提取到的图片src已被加密,如果要获取图片的src则首先要将这个奇葩解密。解密需要请求页面获得两个信息,一个是每张图片的hash值,这个用于之后解密生成图片的信息,另一个是提取关键JS文件的地址每张图片的JS地址是不同的,所以需要从页面中提取得到了hashJS的关键参数后,可以根据JS提供的解密方式得到图片链接(膜拜大神的解密方法 : )

def _md5(value):
    '''md5加密'''
    m = hashlib.md5()
    m.update(value.encode('utf-8'))
    return m.hexdigest()


def _base64_decode(data):
    '''bash64解码,要注意原字符串长度报错问题'''
    missing_padding = 4 - len(data) % 4
    if missing_padding:
        data += '=' * missing_padding
    return base64.b64decode(data)


def get_imgurl(m, r='', d=0):
    '''解密获取图片链接'''
    e = "DECODE"
    q = 4
    r = _md5(r)
    o = _md5(r[0:0 + 16])
    n = _md5(r[16:16 + 16])
    l = m[0:q]
    c = o + _md5(o + l)
    m = m[q:]
    k = _base64_decode(m)
    h = list(range(256))
    b = [ord(c[g % len(c)]) for g in range(256)]

    f = 0
    for g in range(0, 256):
        f = (f + h[g] + b[g]) % 256
        tmp = h[g]
        h[g] = h[f]
        h[f] = tmp

    t = ""
    p, f = 0, 0
    for g in range(0, len(k)):
        p = (p + 1) % 256
        f = (f + h[p]) % 256
        tmp = h[p]
        h[p] = h[f]
        h[f] = tmp
        t += chr(k[g] ^ (h[(h[p] + h[f]) % 256]))
    t = t[26:]
    return t


def get_r(js_url):
    '''获取关键字符串'''
    js = requests.get(js_url).text
    _r = re.findall('c=f_[\w\d]+\(e,"(.*?)"\)', js)[0]
    return _r


def get_urls(url):
    '''获取一个页面的所有图片的链接'''
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0',
        'Host': 'jandan.net'
    }
    html = requests.get(url, headers=headers).text
    js_url = 'http:' + re.findall('<script src="(//cdn.jandan.net/static/min/[\w\d]+\.\d+\.js)"></script>', html)[-1]
    _r = get_r(js_url)
    soup = BeautifulSoup(html, 'lxml')
    tags = soup.select('.img-hash')
    for tag in tags:
        img_hash = tag.text
        img_url = get_imgurl(img_hash,_r)
        print(img_url)


if __name__ == '__main__':
    get_urls('http://jandan.net/ooxx/page-44')

将图片解密后可以提取图片的地址 :

图片的地址提取完成后,在地址的最前面加上“http:" ,在万维网中,指向某一图片的地址是唯一的,所以只需获取图片地址以及图片的二进制数据就可以访问图片了。最后将图片保存在本地即可。

imgs = requests.get(img_url,headers=headers)
filename = img_url.split('/')[-1]
with open(filename, 'wb') as f:
    # 直接过滤掉保存失败的图片
    try:
        f.write(imgs.content)
        print('Sucessful image:',filename)
    except:
        print('Failed:',filename)
def mkdir(path):
    isExists = os.path.exists(os.path.join("F:\jiandan", path))
    if not isExists:
        print('makedir', path)
        os.makedirs(os.path.join("F:\jiandan", path))
        os.chdir(os.path.join("F:\jiandan", path))
        return True
    else:
        print(path, 'already exists')
        return False

完成爬取。

特别提醒 : 身体最重要,别乱爬图片。。。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值