抓取sankakucomplex图片

发布于 2018-10-28  63 次阅读


爬取sankakucomplex的图片

学习python 两个月了,终于自己动手做了一个爬虫,如有什么错误还望斧正!
以下是爬取图片的思路
1.用requests库爬取到图片url
2.用BeautifulSoup4库把爬取到的respond内容解析
3.用os库把二进制图片保存到本地

1.requests库获得到图片url

import requests
url="https://chan.sankakucomplex.com"
kv = {'user-agent': 'Chrome/10.0'}
r = requests.get(url,headers = kv)
r.raise_for_status()
r.encoding = r.apparent_encoding
print(r.text)

在这里插入图片描述
我们发现img的标签下面全都是preview的图片,这不是我们想要的图片url,因此我们必须要找到原图的url。
然而,原图的url不在这个html的里面,因此我们需要访问子连接,进入到例如https://www.sankakucomplex.com/post/show/7201242的网址中
2.BeautifulSoup4库的使用

import requests
from bs4 import BeautifulSoup
import re
url = "https://chan.sankakucomplex.com"
kv = {'user-agent': 'Chrome/10.0'}
r = requests.get(url,headers = kv)
r.raise_for_status()
r.encoding = r.apparent_encoding
soup = BeautifulSoup(r.text,'html.parser')  #用bs4库把r.text做成(一锅汤)
print(soup.prettify())  #完美的显示html

我们看到在这里插入图片描述
span标签中保存着id =‘p7217638’的信息,因此我们想要把这个提取出来:以下提供两种思路。*一.提取id的信息,并把字符串中的'p'去除。二.在a标签中提取出href key所对应的内容。*
**这是第一中方法的代码:

import re,requests
form bs4 in BeautifulSoup
url="https://chan.sankakucomplex.com"
kv = {'user-agent': 'Chrome/10.0'}
        r = requests.get(url,headers = kv)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        soup = BeautifulSoup(r.text,'lxml')
        p_list =[]
        p_list2 =[]
        for p in soup.find_all('span', 'thumb blacklisted', id=re.compile('p')):  #可以使用正则表达式搜索
            p_list.append(p['id'])    #提取id信息,并用append方法把他添加到p_list列表中
        for a in p_list:      #对p_list进行遍历,把p字母去除
            s = re.findall("\d+", a)[0]
            p_list2.append('https://chan.sankakucomplex.com/post/show/' + s)  #整合成url加入到p_list2列表中

第二种方法(此方法之前试验过,但似乎href不是一个key):略

有能力的可以自己尝试,尝试。

我们就通过这些方法得到了每一个网页的url
用for遍历出保存在p_list2列表中的url
打印出了图片进入的url

我们在重复一遍一般requests和BeautifulSoup,提出例如这一个url的信息,https ://chan.sankakucomplex.com/post/show/722035 。

        for u in p_list2:  #将列表中的url,遍历出来
            kv = {'user-agent': 'Chrome/10.0'}
            r = requests.get(u,headers=kv)
            r.raise_for_status()
            r.encoding = r.apparent_encoding
            soup = BeautifulSoup(r.text, 'lxml')
            soup2 = soup.find_all('a',id='highres')
            url_list = []
            for a in soup2:
                url_list.append('https:'+ a ['href'])

这样我们就把图片的真是url地址保存在了url_list的列表中了

3.os库保存图片,视频等二进制文件:

def download(url,root):   #构造一个下载的函数
    #这是下载图片的函数
    try:
        path = root + url.split('/')[-1]  #path环境
        if not os.path.exists(root):  #创建文件夹
                    os.mkdir(root)
        if not os.path.exists(path):  
            r = requests.get(url)
            with open(path, 'wb') as f:   #写入二进制文件
                f.write(r.content)
                f.close()    #要注意把这个关闭
                print("文件已保存")
        else:
            print("文件已存在")
    except:
        print('爬取失败')

我们通过os库,保存二进制图片,视频。并且我们使用爬虫时,要使用try,except 避免出现错误而导致整个程序终止。
并且root是保存图片的本地地址:注意注意注意
windows与linux的地址不一样
windows 例如 root = "D://pics//"
Linux例如 root = "./beta/"
以下放上整体的代码,可以自己爬一爬,玩玩哦!!!

import requests
import urllib
import os
import lxml
from bs4 import BeautifulSoup
import re
import shutil
from urllib import request
def get_url1(url):
    #这是用来打开每一个图片的url
    try:
        kv = {'user-agent': 'Chrome/10.0'}
        r = requests.get(url,headers = kv)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        soup = BeautifulSoup(r.text,'lxml')
        p_list =[]
        p_list2 =[]
        for p in soup.find_all('span', 'thumb blacklisted', id=re.compile('p')):
            p_list.append(p['id'])
        for a in p_list:
            s = re.findall("\d+", a)[0]
            p_list2.append('https://chan.sankakucomplex.com/post/show/' + s)
        return p_list2
    except:
        print("爬取失败")
#root ="C://爬片//"
def download(url,root):
    #这是下载图片的函数
    try:
        path = root + url.split('/')[-1]
        if not os.path.exists(root):
                    os.mkdir(root)
        if not os.path.exists(path):
            r = requests.get(url)
            with open(path, 'wb') as f:
                f.write(r.content)
                f.close()
                print("文件已保存")
        else:
            print("文件已存在")
    except:
        print('爬取失败')
def get_url_download():

    try:
        p_list2 = get_url1("https://chan.sankakucomplex.com")
        for u in p_list2:
            kv = {'user-agent': 'Chrome/10.0'}
            r = requests.get(u,headers=kv)
            r.raise_for_status()
            r.encoding = r.apparent_encoding
            soup = BeautifulSoup(r.text, 'lxml')
            soup2 = soup.find_all('a',id='highres')
            for a in soup2:
                url ='https:'+ a ['href']
                download(url,"./beta/")
        #urllib.request.urlretrieve(url,'D://pic//%s.jpg'%x)
    except:
        print("爬取错误")

def re_name(path):
    #这是一个给文件重命名的模块
    import os
    import re
    a = 0
    name = os.listdir(path)
    for n in name:

        if ".jpg" in n:
            os.rename('./beta/' + n, './beta/' + '%d.jpg' % a)
        elif ".png" in n:
            os.rename('./beta/' + n, './beta/' + '%d.png' % a)
        elif ".mp4" in n:
            os.rename('./beta/' + n, './beta/' + '%d.mp4' % a)
        elif ".webm" in n:
            os.rename('./beta/' + n, './beta/' + '%d.webm' % a)
        else:
            print("未知格式")
        a+=1

get_url_download()
re_name("./beta/")

以上代码使用于Linux的系统
不过我们发现这个爬取得到的文件都是没有文件后缀名的
这是由于该网站的图片真实url都不是又.jpg.png等文件后缀名结尾的,这样就导致了爬取到的文件是无法直接打开的。因此,我们可以自己再写一个python脚本,对多个文件批量命名加后缀。
首先我们导入os库
其次再用os库中的rename方法命名
给出rename方法的使用 os.rename("这里填写源文件的绝对or相对地址","这里填写文件的绝对or相对地址 加上 要改的名字")

def re_name(path): 
    #这是一个给文件重命名的函数
    import os
    a = 0
    c = 0
    e = 0
    f = 0
    g = 0
    name = os.listdir(path)
    for n in name:

        if ".jpg" in n:
            os.rename(path + n, path + '%d.jpg' % a)
            a+=1
        elif ".png" in n:
            os.rename(path + n, path + '%d.png' % c)
            c+=1

        elif ".mp4" in n:
            os.rename(path + n, path + '%d.mp4' % e)
            e+=1
        elif ".webm" in n:
            os.rename(path + n, path+ '%d.webm' % f)
            f+=1    
        elif ".gif" in n:
            os.rename(path + n, path + '%d.webm' %g)
            g+=1
        else:
            print("未知格式")

这是一个普通的重命名函数,用os.listdir()导入文件名字,并把它保存到name列表中。
再通过遍历把每个名字提取出来,分别进行命名。
同时,这个函数是没有返回值的,因此不需要使用return语句。
在调用这个函数的时候只需要在这个函数中填入path,主要这个path要是一个字符串.
快来试试吧!!!


公交车司机终于在众人的指责中将座位让给了老太太