第056讲: 论一只爬虫的自我修养4:OOXX | 学习记录(小甲鱼零基础入门学习Python)

(标答出处: 鱼C论坛)
《零基础入门学习Python》


本节知识点:


今天我们结合前面学习的知识,进行一个实例,从网络上下载图片,话说我们平时闲来无事会上煎蛋网看看新鲜事,那么,熟悉煎蛋网的朋友一定知道,这里有一个 随手拍 的栏目,我们今天就来写一个爬虫,自动抓取每天更新的 随手拍。
第056讲: 论一只爬虫的自我修养4:OOXX | 学习记录(小甲鱼零基础入门学习Python)_第1张图片
要写爬虫,首先要做的第一件事就是踩点,主动发现网页之间的规律,还有图片链接之间有什么规律,例如说,该网站的链接形式为:http://jandan.net/ooxx/page-‘页码数’#comments, (页码数应该小于等于当天的页码数(即目前最大页码数)),

1.那我们怎样获取目前最大的页码数呢(最新页码),我们在页码[77]这个位置点击右键,审查元素,看到了[77]

第056讲: 论一只爬虫的自我修养4:OOXX | 学习记录(小甲鱼零基础入门学习Python)_第2张图片
我们完全可以通过搜索 current-comment-page 在后面偏移 3 位就可以得到 77 这个最新的页面,因为你不能去输入一个具体的数字,因为这里的数字每天都会改变。

2.我们在图片的位置点击右键,审查元素,发现了图片的地址,都是来自于新浪,然后都在 img 标签里,我们就可以使用 img src 作为关键词来进行查找,搜索到了图片的地址就可以参照我们之前下载一只猫的例子了。把下面图片的地址用 urlopen() 打开,然后将其 save 到一个文件里去(二进制),就可以了。


第056讲: 论一只爬虫的自我修养4:OOXX | 学习记录(小甲鱼零基础入门学习Python)_第3张图片
我们弄清楚了以上几点,就可以开始写我们的爬虫程序啦…

(我们抓取前10页的图片,保存到指定的本地文件夹中)

下面是老师讲的代码:

#从煎蛋网的随手拍栏目下载图片
import urllib.request
import os
import random
 
def url_open(url):
        req = urllib.request.Request(url)
        req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36')
        
        #使用代理(就加入下面五行)
        #proxies = ['119.6.144.70:81', '111.1.36.9:80', '203.144.144.162:8080']
        #proxy = random.choice(proxies)
 
        #proxy_support = urllib.request.ProxyHandler({'http':proxy})
        #opener = urllib.request.build_opener(proxy_support)
        #urllib.request.install_opener(opener)
 
        response = urllib.request.urlopen(url)
        html = response.read()
        return html    
 
def get_page(url): #得到最新页面的页码数
        html = url_open(url)
        html = html.decode('utf-8') #因为要以字符串的形式查找,所以要 decode
 
        #然后就是查找 html 中的 'current-comment-page'
        a = html.find( 'current-comment-page') + 23  #加上 23 位偏移就刚到到页码数的第一位数字
        b = html.find(']', a)  #找到 a 位置之后的第一个方括号所在位置的索引坐标
               
        return html[a : b]  #这就是最新的页码数啦
 
def find_imgs(url):  #给一个页面的链接,返回所有图片地址组成的列表
        html = url_open(url).decode('utf-8')
        img_addrs = []  #声明一个保存图片地址的列表
 
        #查找图片地址        
        a = html.find('img src=')        
        while a != -1:
                b = html.find('.jpg', a, a+255) #在 a 到 a+255 区间找 '.jpg',防止有不是 '.jpg' 格式的图片
                #如果 b 找不到,b 就返回 -1        
                if b != -1:
                        img_addrs.append(html[a+9: b+4])
                else:
                        b = a + 9
 
                a = html.find('img src=', b)
 
        return img_addrs
                             
def save_imgs(folder, img_addrs):
        for each in img_addrs:
        filename = each.split('/')[-1]
        with open(filename, 'wb') as f:
                img = url_open(each)
                f.write(img)
 
 
def download_figures(folder = 'figures', page = 10):
        os.mkdir(folder)  #创建文件夹
        os.chdir(folder)
 
        url = "http://jandan.net/ooxx/"  #随手拍栏目的链接,也是最新页面的链接
        page_num = int(get_page(url)) #得到最新页面的页码数
 
        for i in range(page):                
                page_url = url + 'page-' + str(page_num) + '#comments'  #得到要爬取的页面的链接
                print(page_url)
                img_addrs = find_imgs(page_url)  #得到页面所有图片的地址,保存为列表
                save_imgs(folder, img_addrs)  #保存图片到本地文件夹
                page_num -= 1  #逐步找到前几个页面
 
if __name__ == '__main__':
        download_figures()                   

但是由于现在大多数网站都对图片进行了加密,所以这种方法已经不能爬取到 .jpg,这是因为这个网站已经被加密了。

怎样判断一个网站被加密了,就是使用urllib.urlopen导出html文本和审查元素中相应字段对不上。

以后你会发现对不上是常态,一般是JS加密的 可以说大一点的网站这些信息都会对不上。

那怎么解决呢?

目前我只用的一种方法就是:使用selenium爬取js加密的网页

需要详细讲解的可以查看:python使用selenium爬取js加密的网页

所以代码就是下面这样子了:

#从加密的煎蛋网的随手拍栏目下载图片
from selenium import webdriver
import urllib.request
import os

def url_open(url):  #返回普通不加密网页的源码(速度快)
        req = urllib.request.Request(url)
        req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36')
        response = urllib.request.urlopen(url)
        html = response.read()
        return html
 
def url_open_jm(url):   #返回加密网页的源码(速度慢)
        chrome = webdriver.Chrome()
        chrome.get(url)
        html = chrome.page_source
        return html #返回的就是字符串
       
'''
def get_page(url): #得到最新页面的页码数(可以使用不加密读码得到,为了加快速度)
        html = url_open(url)
        
        #然后就是查找 html 中的 'current-comment-page'
        a = html.find( 'current-comment-page') + 23  #加上 23 位偏移就刚到到页码数的第一位数字
        b = html.find(']', a)  #找到 a 位置之后的第一个方括号所在位置的索引坐标
                
        return html[a : b]  #这就是最新的页码数啦
'''

def get_page(url): #得到最新页面的页码数
        html = url_open(url)
        html = html.decode('utf-8') #因为要以字符串的形式查找,所以要 decode
 
        #然后就是查找 html 中的 'current-comment-page'
        a = html.find( 'current-comment-page') + 23  #加上 23 位偏移就刚到到页码数的第一位数字
        b = html.find(']', a)  #找到 a 位置之后的第一个方括号所在位置的索引坐标
               
        return html[a : b]  #这就是最新的页码数啦
 
def find_imgs(url):  #给一个页面的链接,返回所有图片地址组成的列表
        html = url_open_jm(url)  #这个必须使用加密打开的方式
        
        img_addrs = []  #声明一个保存图片地址的列表
        
        #查找图片地址
        #加密的网页破解后得到的图像在这里:
        #
        #所以要先找jpg,然后找img src=
        
        a = html.find('.jpg') 
        while a != -1:
                b = html.rfind('img src=', a-100, a) #在 a-100 到 a区间找 'img src=',必须反向查找
                
                #如果 b 找不到,b 就返回 -1        
                if b != -1:                        
                        img_addrs.append(html[b+9: a+4])
                
                a = html.find('.jpg', a+4)
        for each in img_addrs:
                print(each)
 
        return img_addrs               
                
def save_imgs(folder, img_addrs):
        for each in img_addrs:
                filename = each.split('/')[-1]
                with open(filename, 'wb') as f:
                        img = url_open(each)
                        f.write(img)
 
def download_figures(folder = 'figures', page = 2):
        os.mkdir(folder)  #创建文件夹
        os.chdir(folder)
 
        url = "http://jandan.net/ooxx/"  #随手拍栏目的链接,也是最新页面的链接
        page_num = int(get_page(url)) #得到最新页面的页码数
 
        for i in range(page):
        
                page_url = url + 'page-' + str(page_num) + '#comments'  #得到要爬取的页面的链接
                print(page_url)
                img_addrs = find_imgs(page_url)  #得到页面所有图片的地址,保存为列表
                save_imgs(folder, img_addrs)  #保存图片到本地文件夹
                page_num -= 1  #逐步找到前几个页面
 
if __name__ == '__main__':
        download_figures()

你可能感兴趣的:(第056讲: 论一只爬虫的自我修养4:OOXX | 学习记录(小甲鱼零基础入门学习Python))