爬取图片首先是找规律。
这里以京东搜索手机为例。
得到如下的请求连接
https://search.jd.com/Search?keyword=手机&wq=手机&page=1&s=30&click=0
如上图,是一个手机的商品列表展示页面,我们的目的就是爬取出所有的这些商品上面的图片。我们可以先试着切换一些底部的页面数字按钮,可以发现一个规律,page的值为奇数,s=page*30,其他都固定不变。
于是,我们可以想整出一个访问所有页面的方法,如下:
for i in range(1,100):
page=2*i-1
s= page*30
data_query = {
'keyword':'手机',
'wq': '手机',
'page':page,
's':s,
'click':0
}
url = 'https://search.jd.com/Search?'+urllib.parse.urlencode(data_query)
craw(url,i) #具体的爬取某个页面图片的方法
需要将参数用urllib.parse.urlencode
进行编码再拼接,不然会报错。
编码后的url格式为:
https://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA&wq=%E6%89%8B%E6%9C%BA&page=1&s=30&click=0
craw
方法是具体的爬取某个页面里面的手机图片的方法,接下来我们开始讲解怎么写这个方法。
这边我们用谷歌浏览器进行查看。这应该是程序员应该都懂的使用技巧了。可以打开开发者工具(鼠标右键-‘检查“得到对应的页面)。
要爬取列表对应的图片,我们就得先知道对应组件的html的代码格式,因为是商品列表,那么只要知道一处的组件结构,那么其他位置的结构也应该是一样的。
我们点击1的位置,这样在页面上进行点击就可以索引到对应的html代码的位置。比如我们点击2的图片,就会自动索引到3相应的html代码。是不是特别便捷。然后开始分析这个html代码的规律。
其实我们主要需要的就是img里面对应的src图片地址而已,所以通过正则表达式就可以很容易过滤出来。如下:
pat=’<img width="220" height="220" data-img="1" src=“//(.+?.jpg)”>’
平均一个网页里面可以通过正则表达式匹配到一定数量的对应图片的地址,可以通过urllib.request.urlretrieve
加载图片地址到对应的文件夹。
然而实际运行的时候,发现并不能下载到对应的图片,为什么呢?原来我上面通过开发者工具索引到的html代码跟实际代码其实是有出入的,用正则的话需要匹配的是网页的源代码,直接通过右键-查看网页源代码,
在里面找到实际的代码,如下图:
其实我们主要需要的就是img里面对应的src图片地址而已,所以通过正则表达式就可以很容易过滤出来。如下:
pat = '<img width="220" height="220" data-img="1" src="//(.+?.jpg)" data-lazy-img="done" />'
完整的代码如下:
import re
import urllib.request
import urllib.parse
import ssl
def craw(url,page):
ssl._create_default_https_context = ssl._create_stdlib_context
req = urllib.request.Request(url)
req.add_header("User-Agent",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) "
"AppleWebKit/537.36 (KHTML, like Gecko)"
" Chrome/73.0.3683.103 Safari/537.36")
html1=urllib.request.urlopen(req).read()
html1=str(html1)
pat = '<img width="220" height="220" data-img="1" src="//(.+?.jpg)" data-lazy-img="done" />'
imagelist=re.compile(pat).findall(html1)
x=1
for imageurl in imagelist:
imagename="/Users/zhouruiyong/Desktop/python/img/"+str(page)+"_"+str(x)+".jpg"
imageurl="http://"+imageurl
try:
urllib.request.urlretrieve(imageurl,filename=imagename)
except urllib.error.URLError as e:
if hasattr(e,"code"):
x+=1
if hasattr(e,"reason"):
x+=1
x+=1
for i in range(1,100):
page=2*i-1
s= page*30
data_query = {
'keyword':'手机',
'wq': '手机',
'page':page,
's':s,
'click':0
}
url = 'https://search.jd.com/Search?'+urllib.parse.urlencode(data_query)
craw(url,i) #具体的爬取某个页面图片的方法
运行程序即可以爬取到想要的图片保存在对应的文件里面。
这里有几个需要特别注意,因为地址是https,所以需要加入
ssl._create_default_https_context = ssl._create_stdlib_context
另外header也是需要加入User-Agent字段的,不然可能会报错。
上面通过开发者工具索引代码的方法虽然这边用不了,但是我们后面讲到的用xpath等方式匹配想要的内容将会非常方便。具体我们到后面的章节会讲。
欢迎关注本人公众号和小程序,谢谢