问题:爬取淘宝中某一商品的全部高清图片,并存储到本地。
打开淘宝网,比如搜索真丝连衣裙,可以在地址栏中看到第一页的链接如下:
第二页的链接如下:
第三页的链接如下:
仔细比较一下之后可以发现差别在于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
我们需要做的是爬取每一个商品的图片,注意到要是高清图片而不是缩略图。把鼠标放到一张图片上,右键copy image address
在新的浏览器窗口中打开:
在浏览器中打开之后可以看到的是,这是一张缩略图,而不是我们想要的高清图片。此时分析该缩略图的内容:
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"
而在浏览器地址栏中图片的地址为:
差别之处在于加上了“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
然后是:
对应的搜索结果为:
接下来是:
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')