def req_url(): req = urllib2.urlopen(url="https://coding.imooc.com/") # 打开图片列表页面 buf = req.read() # 读取图片列表页面 buf = buf.decode("utf-8") # 将Unicode 转换为字符串 python3中返回的是unicode url_list = re.findall(r"//.+szimg.+\.jpg", buf) # 提取图片url信息列表 return url_list def image_save(): i = 1 for url in req_url(): url = "http:" + url # 图片url拼接 # print(url + "\n") # 打印图片url f = open("album/" + str(i) + ".jpg", "wb") # 打开图片存放地址 以二进制格式打开,因为是图片 try: req = urllib2.urlopen(url) # 打开图片url buf = req.read() # 读取图片信息 f.write(buf) # 保存图片 i += 1 finally: if f: f.close()
打开方式用wb试一下
厉害了我的同学
网页更新了,你可以这样写:
先把//双斜杠打头的这些给抓出来,再在前面加上 added_str = 'http:'
再操作就行了
程序在windows下运行需要写一个相对路径,如:把 str(i)+'\.jpg'变成'D:\\'+str(i)+'\.jpg',图片就会生成在D盘根目录下:)
需要转成list.
python里边结尾不用写分号
直接写入,你保存的就是一个地址,打开在读取之后保存的才是图片
#listurl = re.findall(r'//img.+?\.jpg', buf) 这样的贪婪模式下会下载两次一样的图片,改成下方那种
listurl = re.findall(r'src=".+?\.jpg', buf)
#前面没有了http:,手动加上
for index,app_id in enumerate(listurl):
listurl[index] = str(app_id).replace('src="', 'http:')
print(index, listurl[index])
print(listurl)
上面buf = req.read()改成
buf = req.read().decode('utf-8')
.是匹配任意字符,如果不加\,就是用.匹配的.
举个例子:
图片后缀都是.jpg,如果不加\,用.去匹配,有可能是xxxxxjpg,而不是xxxxx.jpg,就不是图片了
import urllib.request
把20行去掉,18行改成
f = open(str(i)+'.jpg', 'wb+')
试试看
可以在req = urllib2.urlopen('http:'+url)上面 print 'http:'+url, 就会发现问题所在。listurl = re.findall(r'//.+\.jpg*',buf)这个地方的正则错误,应该使用非贪婪匹配模式,改为listurl = re.findall(r'//.+?\.jpg',buf),即可。
listurl = re.sub(r'src="','http:',str(listurl))的这一步结果是一个str,还需要再将地址匹配出来,多写一步:
listurl = re.findall(r'http:.+?\.jpg'),这样得到的结果是list
values = re.findall(r"src.*? ", res)
values = [t[len("src="):len(t) - 1] for t in values]
import re
import urllib
req = urllib.request.urlopen('http://www.imooc.com/course/list')
#此处加上decode(),不然拿下来的数据都是乱码
buf = req.read().decode("utf-8")
#老师讲课的url地址已经发生改变,改一下正则匹配就好
# listurl = re.findall(r'src=.+\.jpg', buf)
listurl = re.findall(r'//img.+?\.jpg', buf)
# 改成非贪婪模式就行了
#前面没有了http:,那么这里手动加上
for index,app_id in enumerate(listurl):
listurl[index] = str(app_id).replace('//', 'http://')
print(index, listurl[index])
print(listurl)
i = 0
for url in listurl:
#写入模式修改为“wb+”,不然不支持将bytes写入,亲测
f = open(str(i)+".jpg", "wb+")
req = urllib.request.urlopen(url)
buf = req.read()
f.write(buf)
i+=1
import re
import urllib
req = urllib.request.urlopen('http://www.imooc.com/course/list')
#此处加上decode(),不然拿下来的数据都是乱码
buf = req.read().decode("utf-8")
#老师讲课的url地址已经发生改变,改一下正则匹配就好
# listurl = re.findall(r'src=.+\.jpg', buf)
listurl = re.findall(r'//img.+?\.jpg', buf)
# 改成非贪婪模式就行了
#前面没有了http:,那么这里手动加上
for index,app_id in enumerate(listurl):
listurl[index] = str(app_id).replace('//', 'http://')
print(index, listurl[index])
print(listurl)
i = 0
for url in listurl:
#写入模式修改为“wb+”,不然不支持将bytes写入,亲测
f = open(str(i)+".jpg", "wb+")
req = urllib.request.urlopen(url)
buf = req.read()
f.write(buf)
i+=1
f.close()
转义字符,因为 . 在正则中表示任意一个字符,但这段代码需要的是 (.jpg),这里面的. 就是. 本身,并不需要它表示任意一个字符,所以需要转义它,\. 代表转义。
我用的pycharm,今天才手写的代码,改了几个小地方,都写在注释里面,楼主看看注意到没有,谢谢。
import re
import urllib
req = urllib.request.urlopen('http://www.imooc.com/course/list')
#此处加上decode(),不然拿下来的数据都是乱码
buf = req.read().decode("utf-8")
#老师讲课的url地址已经发生改变,改一下正则匹配就好
# listurl = re.findall(r'src=.+\.jpg', buf)
listurl = re.findall(r'//img.+?\.jpg', buf)
# 改成非贪婪模式就行了
#前面没有了http:,那么这里手动加上
for index,app_id in enumerate(listurl):
listurl[index] = str(app_id).replace('//', 'http://')
print(index, listurl[index])
print(listurl)
i = 0
for url in listurl:
#写入模式修改为“wb+”,不然不支持将bytes写入,亲测
f = open(str(i)+".jpg", "wb+")
req = urllib.request.urlopen(url)
buf = req.read()
f.write(buf)
i+=1
cat命令是查看文件内容,你直接看图片,它就把图片内容转换成十六进制给你显示出来了。你应该是在linux下遇到的这个情况,我是直接在windows下做的,所以没这个脚本。你可以考虑使用共享文件夹,然后再在windows下查看,或者用老师那个xftp工具
1.url地址必须是http://或者 https:// 这样才行啊
2.python 3.x中urllib库和urilib2库合并成了urllib库
在用户本地文件下
这个涉及写的时候URL重定向类似的问题,没影响的,是网页本身的问题,和你爬的没关系。
应该是网页的代码有变化了。
我的参考代码是这样的!:
import re
import requests
import os
def geturl():
if not os.path.exists("D:\\IMMOC"):
os.makedirs("D:\\IMMOC")
count=1
res=requests.get('http://www.imooc.com/course/list')
re_search=re.findall(r'src=.*\.jpg',res.text)
for each_url in re_search:
jieguo=re.search(r'http:.*\.jpg',each_url)
jieguo.group()
with open('D:\\IMMOC\\'+str(count)+'.jpg','wb') as file:
req_get=requests.get(jieguo.group())
file.write(req_get.content)
print('NO '+str(count)+' picture download successfully')
count+=1
geturl()
listurl = re.findall(r'http.+?\.jpg', buf) 改成非贪婪模式就行了
我自己试了一下,发现会读取出这种如图1的结果,我个人猜测是因为在正则表达式中使用了+这个贪婪模式的字符,所以会尽量匹配多的字符,所以看图中就知道,它把两个地址的字符串都匹配进去了,因为两个字符串连接在一起也是http开头,.jpg结尾的,把“listurl = re.findall(r'http:.+\.jpg',buf)”改成“listurl = re.findall(r'http:.+?\.jpg',buf)”,读取的结果就正确了。以上是个人观点,如有不足之处还望指出。