python爬虫入门-煎蛋网妹子图片下载

知识点:多线程/BeautifulSoup/正则表达式/hashlib/base64/requests

参考:

python爬虫之反爬虫情况下的煎蛋网图片爬取初步探索



煎蛋网的反扒用了个障眼法..首页读出的img地址是类似这样的.

span><p><img src="//img.jandan.net/img/blank.gif" onload="jandan_load_img(this)" /><span class="img-hash">Ly93eDEuc2luYWltZy5jbi9tdzYwMC8wMDc2QlNTNWx5MWZzejZ6eGlqZzlqMzBtODB4Y3dqai5qcGc=span>p>
                        div>
表面上看是加密了,需要js文件中的
"jandan_load_img(this)
这个方法才能解开,在js文件中找到此方法后,非常复杂的一段...但其实用base64的.decode对这一段直接解码,就出现真实网址了....


import requests
import base64
import re
from bs4 import BeautifulSoup
import threading
import hashlib 
import math
import lxml

header = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0'}

# 解析加密img图片的方法,返回真实imgurl地址列表
def parse_img_url(pages):
    print('parse_img_url start')
    real_img_url = []  # 真实img地址
    for i in pages:
        # 使用BeautifulSoup解析为xml形式,方便查找html节点
        soup = BeautifulSoup(i, 'lxml')
        # 根据class属性值查找加密的imgurl所在
        imgurl = soup.find_all(class_='img-hash')
        for j in imgurl:
            # 转为真实地址
            url=j.text
            url = base64.b64decode(url).decode('utf-8')
            real_img_url.append(url)
    print('parse_img_url end')
    return real_img_url


# 下载图片的方法
# suffix和url_dase64是为了命名而存在
def downloadimg(url, header):
    print('downloadimg start',url)
    # 利用hashlib生成文件名
    md5 = hashlib.md5()
    md5.update(url.encode('utf-8'))
    filename = md5.hexdigest()
    print('filename:',filename,'\n','type;',type(filename))
    # 补全url
    url = 'http:' + url
    # 提取文件后缀
    suffix = url.split('.')
    suffix = suffix[len(suffix) - 1]

    # 抓取页面
    response = requests.get(url, header)
    img = response.content
    with open('D://meizi/' +filename + '.' + suffix, 'wb') as f:
        f.write(img)
    print('下载成功')


# 自定义线程类
class Spider(threading.Thread):
    print('main.header:',header)
    count=1
    def __init__(self, pages):
        threading.Thread.__init__(self)  # 初始化线程
        self.pages = pages
        print('创建线程',Spider.count)
        Spider.count+=1

    def run(self):
        real_img_url = parse_img_url(self.pages)
        # 下载图片
        for url in real_img_url:
            downloadimg(url, header)


# 主程序
def main(amount):
    print('main start')

    # 当前页面
    current_url = 'http://jandan.net/ooxx'

    """
    多线程抓取页面
    """
    pages = []  # 所有待抓取页面
    threads = []  # 所有工作线程
    try:
        for i in range(amount):
            current_page = requests.get(current_url, headers=header).text  # 当前页源码
            pages.append(current_page)
            current_url = 'http:' + re.search(r'.*Older\sComments\"\shref=\"(.*?)\"\sclass.*', current_page).group(
                1)  # 提取下个页面url
    except Exception as e:
        print('错误',e)
        pass
    t_amount = 10 if len(pages) > 10 else len(pages)  # 页面抓取线程数,最大为10
    for i in range(t_amount):
        # 下方
        # 下方长长的部分,是把查询内容均分为符合生成的线程数量的方式.如线程10,任务为23个页面,就将23个页面均分为10份交与线程处理
        t = Spider(pages[math.ceil(int((len(pages)) / t_amount) * i):math.ceil(int((len(pages)) / t_amount) * (i + 1))])
        threads.append(t)  # 放入生成的线程,布置工作
        # 开始工作
        print('线程池数量,',len(threads))
    for t in threads:
        print(t.name)
        t.start()
    print('下载成功!')

if __name__ == '__main__':
    amount = input('请输入抓取页数后按回车开始(小于100),从首页开始计数):')
    main(int(amount))  # 抓取首页开始的前amount页的图片






 

类的使用说明

import requests
https://www.cnblogs.com/zhaof/p/6915127.html
import base64
https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001399413803339f4bbda5c01fc479cbea98b1387390748000
import re
from bs4 import BeautifulSoup
import lxml
https://cuiqingcai.com/1319.html
import threading
https://www.jb51.net/article/136962.html
import hashlib
https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/0013868328251266d86585fc9514536a638f06b41908d44000 
import math

你可能感兴趣的:(Python)