Python爬虫抓取图片第一次尝试
上一篇日记写了如何写一个最简单的python爬虫,今天开始尝试抓取页面上的图片。
这次参考的是这篇博客里的代码。遇到的第一个问题还是python版本问题。除了上一篇日记里提到的,还要在使用html变量之前加一句html = html.decode("utf-8")
。其他没什么大问题,运行之后就把网页上的图片抓取到本地文件夹了。
成功之后还是有点激动(虽然是别人的代码。我就想“啊这样我随便改个网址就能把上面的图片都抓下来了!”,太天真了。
把网址改成http://douban.com
之后,问题就来了。运行之后报错:
UnboundLocalError: local variable ‘image’ referenced before assignment
查了一下大多数情况下是因为有一个全局变量和局部变量用了一样的变量名,在局部使用全局变量时要global一下,然而…我并没有申明过全局变量啊!
但是这个错确实报的是没有申明变量,我想那我就申明一下好啦,然而…python不用申明变量TAT是可以拿来直接用的啊(目前是这么理解的,于是乎就想到应该是image
变量在return
时还是空的,也就是说函数urllib.request.urlretrieve(imgurl, target, schedule)
返回值为空!
想到这里,就开始判断是哪个参数没有传对导致无法获取正确结果,target
和schedule
都没什么好错的啊从头到尾没改过,大致猜测问题出在imgurl
上,这种时候,就把这个变量输出来看看,是哪里错了(就是这么简单粗暴的调试方法
在循环里加了一句print('url:'+ imgurl)
再次运行,根本没有输出…但是本地文件夹已经创建了,说明确实运行到了这里。那就继续往前找看看imglist
是什么,然后看到了imglist = re.findall(imgre1, html)
噢所以是正则表达式从html
对象里匹配的东西,现在大概就能确定是正则表达式出了问题了。
于是顺便学习了一下正则表达式,主要参考这篇博客 博主还是很厉害讲的非常清楚,看完之后知道原正则表达式src="(.+?\.jpg)" pic_ext
匹配的字符串大概是什么样,前面都很好理解然而非常让我疑惑的一点是pic_ext
这是什么鬼???开始以为是re的语法,最后知道真相的我快被自己蠢哭,啊,这就只是单纯的一个字符串而已,只是原博主抓取的页面里的图片src后面都跟着的东西而已…而豆瓣主页的图片src后面并没有跟这个…所以把正则表达式改成src="(.+?\.jpg)"
就好了。
改好之后点击运行~TADA~成功抓取图片 * 1!可是,等等…为什么只有一张???为什么又报错???
这次报的错是
urllib.error.HTTPError: HTTP Error 400: Bad Request
有点崩溃..TAT妈妈我计网没学好啊我好怕http。不行不行,作为一个未来的程序员,我要冷静,分析,解决问题。先查一下为什么会有这个错先…噢说是请求无效。那我手动访问一下好啦,找到url→
https://img3.doubanio.com/f/shire/a1fdee122b95748d81cee426d717c05b5174fe96/pics/blank.gif” data-origin=”https://img3.doubanio.com/view/photo/albumcover/public/p2345626212.jpg
然后…手动访问失败(废话也不看看这个url长得这么奇怪!
噢所以应该访问的是data-origin之后的那个网址。知道问题出在哪里就好啦(并不是
所以说还是url没抓对,目前想到的办法是(受限于我浅薄的正则表达式及python知识)只要再判断一下imgurl
对象里是否包含字符串data-origin
,包含的话再将imgurl
对象替换成data-origin
后面的字符串应该就ok。
经过半小时的正则表达式 + re.match()
尝试,失败…并不知道问题出在哪里,做了以下尝试:
>>> result = re.match(r'data-origin="(.+?\.jpg)', 'https://img3.doubanio.com/f/shire/a1fdee122b95748d81cee426d717c05b5174fe96/pics/blank.gif" data-origin="https://img3.doubanio.com/view/photo/albumcover/public/p2345626212.jpg')
>>> print(result)
None
>>> result = re.match(r'.+data-origin="(.+?\.jpg)', 'https://img3.doubanio.com/f/shire/a1fdee122b95748d81cee426d717c05b5174fe96/pics/blank.gif" data-origin="https://img3.doubanio.com/view/photo/albumcover/public/p2345626212.jpg')
>>> print(result)
<_sre.SRE_Match object; span=(0, 174), match='https://img3.doubanio.com/f/shire/a1fdee122b95748>
>>> result = re.match(r'data-origin="(.+?\.jpg)', 'https://img3.doubanio.com/f/shire/a1fdee122b95748d81cee426d717c05b5174fe96/pics/blank.gif" data-origin="https://img3.doubanio.com/view/photo/albumcover/public/p2345626212.jpg')
>>> print(result)
None
>>> result = re.match(r'data-origin', 'https://img3.doubanio.com/f/shire/a1fdee122b95748d81cee426d717c05b5174fe96/pics/blank.gif" data-origin="https://img3.doubanio.com/view/photo/albumcover/public/p2345626212.jpg')
>>> print(result)
None
>>> result = re.match(r'data-origin="(.+?\.jpg)', 'data-origin="https://img3.doubanio.com/view/photo/albumcover/public/p2345626212.jpg')
>>> print(result)
<_sre.SRE_Match object; span=(0, 83), match='data-origin="https://img3.doubanio.com/view/photo>
>>> result = re.match(r'data-origin="(.+?\.jpg)', 'https://img3.doubanio.com/f/shire/a1fdee122b95748d81cee426d717c05b5174fe96/pics/blank.gif"data-origin="https://img3.doubanio.com/view/photo/albumcover/public/p2345626212.jpg')
>>> print(result)
None
>>> result = re.match(r'data-origin="(.+jpg)', 'https://img3.doubanio.com/f/shire/a1fdee122b95748d81cee426d717c05b5174fe96/pics/blank.gif" data-origin="https://img3.doubanio.com/view/photo/albumcover/public/p2345626212.jpg')
>>> print(result)
None
所以还是正则表达式的问题,但是今天本程序员累了,先这样吧。等我好好探索一番正则表达式再来解决这个问题…
最后附上这次(还有很多问题的)代码
# -*- coding: utf-8 -*-
#参考http://blog.csdn.net/cruise_h/article/details/25737737?utm_source=tuicool&utm_medium=referral
import urllib.request
import re
import time
import os
#显示下载进度
def schedule(a,b,c):
'''''
a:已经下载的数据块
b:数据块的大小
c:远程文件的大小
'''
per = 100.0 * a * b / c
if per > 100 :
per = 100
print ('%.2f%%' % per)
def getHtml(url):
print ("in getHtml")
page = urllib.request.urlopen(url)
html = page.read()
f = open('out.txt', 'w')
print(html, file = f)
f.close()
return html
def downloadImg(html):
print("in downloadImg")
#reg = r'src="(.+?\.jpg)" pic_ext'
reg1 = r'src="(.+?\.jpg)"'
imgre1 = re.compile(reg1)
reg2 = r'data-origin="(.+?\.jpg)'
imgre2 = re.compile(reg2)
#cannot use a string pattern on a bytes-like object
#版本问题加一句
html = html.decode("utf-8")
imglist = re.findall(imgre1, html)
#定义文件夹的名字
t = time.localtime(time.time())
foldername = str(t.__getattribute__("tm_year"))+"-"+str(t.__getattribute__("tm_mon"))+"-"+str(t.__getattribute__("tm_mday"))
picpath = 'D:\\other\python\Lab03_getjpg\ImageDownload\\%s' % (foldername) #下载到的本地目录
if not os.path.exists(picpath): #路径不存在时创建一个
os.makedirs(picpath)
x = 0
#global(image)
for imgurl in imglist:
#rint('url:'+ imgurl)
if imgre2.match(imgurl):
print('in if')
imgurl = imgre2.match(imgurl)
print('url:'+ imgurl)
target = picpath+'\\%s.jpg' % x
#print ('Downloading image to location: ' + target + '\nurl=' + imgurl)
image = urllib.request.urlretrieve(imgurl, target, schedule)
x += 1
return image;
if __name__ == '__main__':
print ('''****************start*****************''')
html = getHtml("http://douban.com")
downloadImg(html)
print ("Download has finished.")