python爬虫爬取图片

问题:爬取淘宝中某一商品的全部高清图片,并存储到本地。

打开淘宝网,比如搜索真丝连衣裙,可以在地址栏中看到第一页的链接如下:

https://s.taobao.com/list?spm=a21bo.2017.201867-links-0.23.5af911d9LTKdlG&q=%E7%9C%9F%E4%B8%9D%E8%BF%9E%E8%A1%A3%E8%A3%99&cat=16&seller_type=taobao&oetag=6745&source=qiangdiao

第二页的链接如下:

https://s.taobao.com/list?spm=a21bo.2017.201867-links-0.23.5af911d9LTKdlG&q=%E7%9C%9F%E4%B8%9D%E8%BF%9E%E8%A1%A3%E8%A3%99&cat=16&seller_type=taobao&oetag=6745&source=qiangdiao&bcoffset=12&s=60

第三页的链接如下:

https://s.taobao.com/list?spm=a21bo.2017.201867-links-0.23.5af911d9LTKdlG&q=%E7%9C%9F%E4%B8%9D%E8%BF%9E%E8%A1%A3%E8%A3%99&cat=16&seller_type=taobao&oetag=6745&source=qiangdiao&bcoffset=12&s=120

仔细比较一下之后可以发现差别在于s=i*60,可以构造出需查找商品的链接。即:

关键字=

a21bo.2017.201867-links-0.23.5af911d9LTKdlG&q=%E7%9C%9F%E4%B8%9D%E8%BF%9E%E8%A1%A3%E8%A3%99

https://s.taobao.com/list?spm=关键字&cat=16&seller_type=taobao&oetag=6745&source=qiangdiao&bcoffset=12&s=i*60

我们需要做的是爬取每一个商品的图片,注意到要是高清图片而不是缩略图。把鼠标放到一张图片上,右键copy image address

在新的浏览器窗口中打开:

https://g-search1.alicdn.com/img/bao/uploaded/i4/i4/2612360494/TB22ENFhH1YBuNjSszhXXcUsFXa_!!2612360494.jpg_360x360Q90.jpg_.webp

在浏览器中打开之后可以看到的是,这是一张缩略图,而不是我们想要的高清图片。此时分析该缩略图的内容:

https://g-search1.alicdn.com/img/bao/uploaded/i4/i4/2612360494/类似于服务器上的文件目录,而尾部的360x360Q90.jpg学过前端的同学应该都会知道表达的是图片尺寸,!!2612360494.jpg应该是图片的名称,而之前的TB22ENFhH1YBuNjSszhXXcUsFXa有可能就是最关键的信息,所以拿着这一串字符在源代码中搜索,command+f,搜索结果如下:

可以看到图片的在源代码中的内容如下:

"pic_url":"//g-search1.alicdn.com/img/bao/uploaded/i4/i4/2612360494/TB22ENFhH1YBuNjSszhXXcUsFXa_!!2612360494.jpg"

而在浏览器地址栏中图片的地址为:

https://g-search1.alicdn.com/img/bao/uploaded/i4/i4/2612360494/TB22ENFhH1YBuNjSszhXXcUsFXa_!!2612360494.jpg_360x360Q90.jpg_.webp

差别之处在于加上了“http://”,所以在构造高清图片真实地址时需要在前面加上http头部。

所以在构造高清图片的真实路径时,需要使用这些图片的地址爬取高清图片到本地。

代码如下:

# -*- coding: UTF-8 -*-
# author:ray
import urllib.request,re

keyname = '真丝连衣裙'
key = urllib.request.quote(keyname)#由于关键字是英文,所以需要进行quote操作
for i in range(0,100):
    page_urls = 'https://s.taobao.com/list?spm='+key+\
                '&cat=16&seller_type=taobao&oetag=6745' \
                '&source=qiangdiao&bcoffset=12&s='+str(i*60)
    data = urllib.request.urlopen(page_urls).read().decode('utf-8','ignore')
    #"pic_url":"//g-search1.alicdn.com/img/bao/uploaded/i4/i4/2612360494/
    # TB22ENFhH1YBuNjSszhXXcUsFXa_!!2612360494.jpg"
    pattern = '"pic_url":"//(.*?)"'
    img_urls_list = re.compile(pattern).findall(data)
    for j in range(len(img_urls_list)):
        img_now = img_urls_list[j]
        img_now_url = 'http://'+img_now
        filepath = '/Users/mac/Desktop/Learn/GraduateStudent/DataMining/images/dress/'+str(i)+'_'+str(j)
        urllib.request.urlretrieve(img_now_url,filepath)

这里0-100,相当于要爬取100页*60张相片,实在是有一些大了,相对来说也会比较耗时。为了节省时间,将其该为10。

刚才去吃饭没来得及改掉range内的循环次数,回来看到已经爬取了这么多了。

要注意的是,第一层for循环中的range内的循环数,是要根据我们浏览网页时肉眼看出的。

需要指出的是,有些时候可能需要我们记录下此次爬虫的执行时间,可以使用如下代码。

import time
start_time = time.time()
上述代码段
end_time = time.time()
duration = end_time - start_time
print('Running time is % seconds'%duration)

这样可以在执行完毕之后获得此次爬虫的时间。

还有一点要说明的是,一般我会出现文件目录错误的异常,相较于每次都手动去创建相应名称的文件目录。可以在文件中定义一个创建文件夹的函数。在主代码段中调用createdir函数,需要时,只需要改掉filepath即可。

import os
def createdir(path):
    folder = os.path.exists(path)
    if not folder:
        os.mkdir(path)
    else:
        pass
filepath = '/Users/mac/Desktop/Learn/GraduateStudent/DataMining/images/dress/'+str(i)+'_'+str(j)
createdir(filepath)

照道理来说这样做应该已经没问题了,但是在执行的时候出现问题了,因为这样做会不断的创建文件夹,而jpg文件则一直无法命名,要知道+str(i)+'_'+str(j)是用来为jpg文件命名的,所以还需要做相应的改进。改进如下:

main_filepath = '/Users/mac/Desktop/Learn/GraduateStudent/DataMining/images/dress10/'
createdir(main_filepath)
entire_filepath = main_filepath+str(i)+str(j)
urllib.request.urlretrieve(img_now_url,entire_filepath)

最后对以上的不足之处进行改进,再次执行一次,注意这次第一层循环获得的页面数改为5以便能够快速得到结果。这次的搜索关键字为旗袍。在贴一张改进过后的完整代码图,并附上最后执行完毕后得到的图片。

这里出现了一些错误,因我我发现这次执行得到的图片仍然是上次的连衣裙图片。所以有必要分析一下,这是为什么!

旗袍的第二页链接:

https://s.taobao.com/list?spm=a21bo.2017.201867-links-0.22.5af911d9i2uATL&q=%E6%97%97%E8%A2%8D&cat=16&seller_type=taobao&oetag=6745&source=qiangdiao&bcoffset=12&s=60

它对应的页面内容是:

对比之前连衣裙的第二页链接:

https://s.taobao.com/list?spm=a21bo.2017.201867-links-0.23.5af911d9LTKdlG&q=%E7%9C%9F%E4%B8%9D%E8%BF%9E%E8%A1%A3%E8%A3%99&cat=16&seller_type=taobao&oetag=6745&source=qiangdiao&bcoffset=12&s=60

一下子看不出什么差别,那好,我们去淘宝页面搜索一下,对应的字段能否查询到之前的页面内容。

首先是:https://s.taobao.com/list?spm=a21bo.2017.201867-links-0.22.5af911d9i2uATL

然后是:

https://s.taobao.com/list?spm=a21bo.2017.201867-links-0.23.5af911d9LTKdlG&q=%E7%9C%9F%E4%B8%9D%E8%BF%9E%E8%A1%A3%E8%A3%99

对应的搜索结果为:

接下来是:

https://s.taobao.com/list?&q=%E6%97%97%E8%A2%8D&cat=16

搜索结果为:

接下来是:

https://s.taobao.com/list?&q=%E7%9C%9F%E4%B8%9D%E8%BF%9E%E8%A1%A3%E8%A3%99&oetag=6745

至于url中的其他字段就不在此一一列举了,从上述的结果可以分析出:搜索关键字对应的字段是&q=key,只要保证这个字段正确,就能够的看到一些符合key描述的服装。而&s=60则代表页面或者说当前页面的第一件服装。至于其他字段,应该代表的是相应的旗袍风格,相对来说并不重要。所以此时可以知道此前的代码中key的位置放的不正确,此外其他的一些属性也并不需要,在测试一下。并贴上代码:

吃饭之后一直弄这个,忘记了一个重要部分,刚才提交之后又过来修改,就是当我们想要爬取的图片查看图片地址之后,可以得到图片的链接,然后分析,在pagesource中查找如果查找不到,那么可以考虑换一个浏览器,然后如果在这个浏览器中可以查阅到图片地址,那么我们在爬取图片时需要进行浏览器伪装,在inspect-network-headers-user-agent,拷贝下来,然后进行浏览器伪装。

相应的代码如下:

page_urls = 'https://s.taobao.com/list?&q='+key+'&s='+str(i*60)
headers = ('user-agent','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) '
                        'AppleWebKit/537.36 (KHTML, like Gecko)'
                        ' Chrome/67.0.3396.99 Safari/537.36')
#添加headers
opener = urllib.request.build_opener()
opener.addheaders = [headers]
urllib.request.install_opener(opener)#设置为全局模式
data = urllib.request.urlopen(page_urls).read().decode('utf-8','ignore')

猜你喜欢

转载自blog.csdn.net/LawenceRay/article/details/81177952