Python学习记录之一爬图片

来源:互联网 发布:卡通农场数据恢复 编辑:程序博客网 时间:2024/04/30 00:38
    最近在学python,一搜python搜出来很多关于爬虫的信息,大概看了一下,感觉挺有意思的,于是呢,也来学着写写,先从最简单的爬图片开始吧。搜了几个图站,都不太满意,倒不是说图片不好看,而是要么页面广告多,要么乱七八糟的各种东西,恰好这时候发现一个不健康的网站,哈哈,干脆就爬这个算了。    先说一下这要涉及到的知识,主要就是python的两个库,requests和BeautifulSoup,还有需要简单了解一下html的知识。爬网站其实就是模仿浏览器访问网站,以我目前的粗浅理解,整个流程是这样的:1.  调用requests.get方法给目标网站发送一个请求2.  目标网站收到请求之后会返回一个包含有网页源码的对象3.  从源码中找到我们需要的图片的地址4.  用图片地址再次发送get请求,然后把收到的信息保存起来,就是图片啦    下面分析一下将要爬的这个网站,由于是个不健康网站,不方便上图,就分析一下源码吧。这个网站首页有大概100小标题,每个小标题就是一个跳转链接,点击之后会打开一个新的网页,里面有10多张图,我的目标是把这些图片全都下载下来,那么首先需要把这些标题的链接提取出来,然后再在新页面的源码里找到图片的地址。

包含标题链接的标签

    `def get_req(url):print urlreturn requests.get(url)`
def find_a_url(r):     all_url = []    soup = BeautifulSoup(r.text,'lxml')     title = soup.find_all('a', class_ = 'T')    for t in title:        str = t.get('href')        url = re.search('http:.*$',str)        all_url.append(url.group(0))    return all_url
    简单说一下这部分的代码。传入参数r就是requests.get 返回的包含有网页全部信息的一个对象,r.text就是经过解码之后的文本类型的网页信息,经过BeautifulSoup处理成一种特定的结构,方便bs里的方法进一步处理,然后返回这个对象。Find_all方法用于在源码中寻找满足要求的标签,并将所有满足要求的标签存在一个list里返回。然后遍历所有a标签,从里面取出bref这一段,再用正则表达式取出http部分,都存起来,至此,我们就得到了首页所有标题的网址。    接下来,该分析跳转的子网页的源码了,这次是找图片了,应该是更好找了,毕竟图片地址看结尾的后缀很明显,然后呢,看网页可以确定这些图片大概分几个部分,主图的源码肯定是在一起的,广告的源码,还有一些其他小图片的源码肯定都是分开的。看了源码,最笨的方法,图地址一块一块的看,感觉像的放浏览器里试一下,很快就找到了。大图是在div标签下,div style="display: none",有一点不同,每一张图片都是div下的一个子标签,但是不要紧,我们有contents可以遍历出div标签的所有子标签,然后就跟前面一样了,从每一个a标签里拿出href,为了方便测试我把得到到所有图片地址都存到了一个文本里,后面下载的时候直接从文本里读,然后就出了个悲剧。。。    子页面的标签找出来之后是这样,图片传不上来。。。    <div style="display: none"><a href="http://images.xxxxxx.pics/p/hot_babe_akane-ozora-sucks-coc-avidolz/avidolz_01.jpg">    <img src="src="http://images.xxxxxx.pics/p/hot_babe_akane-ozora-sucks-coc-avidolz/avidolz_01.jpg"></a>
def find_src(url):    i = 0    all_src = []    for u in url:        r = get_req(u)        print i        i += 1        soup = BeautifulSoup(r.text,'lxml')        title = soup.find('div', style = 'display: none')        for child in title.contents:            if child.name == 'a':                src = child.get('href')                all_src.append(src)    return all_src

下载函数以及往文件写的函数:

def download(des_path,src_path):    number   = 0    if not os.path.exists(des_path):        os.makedirs(des_path)    with open(src_path,'r') as f:        url = f.readlines()    for u in url:        filename = str(number) + r'.' + 'jpg'           path     = os.path.join(r'/',des_path,filename)        u = u.strip('\n')        with open(path,'wb') as f:            r = requests.get(u)            for chunk in r.iter_content(1000):                f.write(chunk)            print u            print path            print r.status_code        number += 1def write_to_file(file_name,src):    with open(file_name,'w') as f:        for s in src:            f.write(s)            f.write('\n')
    头和尾:
#-*- coding:utf-8 -*-import requestsimport sysimport reimport os.pathfrom bs4 import BeautifulSoupreload(sys)sys.setdefaultencoding('utf-8')if __name__ == '__main__':    url       = 'http://xxxxxx.pics/'    src_path  = 'img_src.txt'    des_path  = 'G:/python/download'    r         = get_req(url)    url       = find_a_url(r)    src       = find_src(url)    write_to_file(src_path,src)    download(des_path,src_path)
    然后就是下载部分了,没什么特别需要强调的,就记录一下出的这个错。我从txt里读取图片地址,然后一个个的传给requests.get去访问,然后就是等着咯,由于有1500多张图片,所以程序运行还是要一定的时间的,中间也没报错,终于终于运行完了的时候,很开心,打开文件夹一看,蒙逼了,全都打不开,白特么等了,再一看,所有的图片都一样大,45个字节,这显然是哪里出错了。这时候不用想肯定是下载部分的代码有问题啊,因为从文本中读出的地址打印出来是正常的,放到浏览器里也能访问,我单个地址穿进去也能下载成功,为啥就加了个循环就不行了呢,非常想不通,怀疑是不是因为写的时候要分多次写,加了循环后有什么未知的影响导致只写了一次。又一想还是不对,就算只写一次,写的大小也是1000而不是45,那么问题就是网站返回的信息就不对。这下更想不明白了,我单独把链接复制到requests里不循环可以下载成功,就加了个循环怎么就不行了呢。然后寻思吧返回的状态码打印出来看一下,一看,返回的是400,意思是之歌网址不对,或者没权限访问,那肯定就是网址不对呗。尼玛,老子狗眼都要瞅瞎了也看不出链接有什么不同。最后写了个列表,把15个地址一个个手动复制进去,另一个列表装的是从文件里读出来的15个地址,然后同时打印出list[0],第一次没看出来,第二次感觉好像哪不对劲,然后注释掉一个,打印另一个对比,尼玛,发现了,从文本里读出来的后面有个换行符,因为我往文本里写的时候,为了好看一点,写一个链接,写一个换行符。然后赶紧找到stirng. Strip(’\n’)这个函数加上,把换行符给去掉,终于一切正常了。    至于代码中这几个方法的用法,文档里写的很清楚,我就不多记录了,都有中文文档,直接百度就出来了,关于html的介绍,就看w3school,很详细。    另:第一次写博客啊,昨晚都快写完了,显示发表成功,结果没发出去,又重新写了一下,主要就是记录一下自己的学习过程,方便以后查阅,新手上路,路过的大神请多多指教。
原创粉丝点击