网址:“https://bing.ioliu.cn/”
知识点:这次我跟之前爬取图片的程序最大的不同是我这次采用了自己设置要采取的页数,然后程序会自动将任务平均分到之间四个线程中,不在跟之前的一样需要人为的设置每个线程要爬取几页,他用到的知识点就是我们简单列表分割。
思路:我输入一个数字,程序把它变为一个列表,然后自动将我们刚才输入数字的列表把它变为一个个的小列表,然后在使用多线程将每个列表中最小值作为要爬取页面的开始页面,最大值作为要爬取页面的结束页面
下面是将一个数字分为指定数量列表的代码:
number = int(input('请输入要爬取的页数:'))
a = [i for i in range(0, number)]#这里是将我输入的页数变为列表
step = 4这里的四就表示我要使用的几个线程
b = [a[i:i + step] for i in range(0, len(a), step)]
但是上面的代码还是用问题,他最多只能使用四个数据
下面是实现上面功能的代码
import requests,random,re,os
from urllib import request
from lxml import etree
from threading import Thread
user_agent = [
"Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)",
"Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
"Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
]
headers={"User-Agent": random.choice(user_agent)}
proxies={
'http':'http://163.204.243.251:9999',
'http':'http://60.13.42.115:9999',
'http':'http://182.35.86.234:9999',
'http':'http://60.13.42.147:9999',
'http':'http://60.13.42.22:9999',
'http':'http://182.35.82.192:9999',
'http':'http://60.13.42.124:9999',
'http':'http://111.230.99.192:8118',
'http':'http://163.204.244.220:9999',
'http':'http://163.204.247.47:9999'
}
class biying_img(Thread):
url='https://bing.ioliu.cn/?p='
def __init__(self, star_page, end_page,flie):
super(biying_img, self).__init__()
self.star_age = star_page
self.end_page = end_page
self.flie=flie
self.list=[]
self.title=[]
self.img=[]
def get_one_page_url(self,page):
'''查找首页图片的url'''
one_url=self.url+str(page)
r=requests.get(one_url,headers=headers,proxies=proxies,timeout=1)
url_list = re.findall(r'class="mark" href="(.*?)">', r.text, re.S)
for i in url_list:
url_headers = 'https://bing.ioliu.cn'
img_url = url_headers + i
self.list.append(img_url)
return self.list
def get_one_data(self,img_url):
'''查找单页的图片和名字'''
d = requests.get(img_url, headers=headers,proxies=proxies,timeout=1)
title = re.findall(r'<title>(.*?)</title>', d.text, re.S)
img = re.findall('img class.*?src="(.*?)" data-progressive', d.text, re.S)
for ti,ig in zip(title,img):
names=ti.split('(')[0]
ig_url=ig
self.title.append(names)
self.img.append(ig_url)
return zip(self.title,self.img)
def mkdirs(self,name):
flie='//Users/qq/desktop/{}/'.format(name)
if os.path.exists(flie):#判断保存的文件夹已经存在则打印已经存在字样
print('文件夹已存在')
else:#如果存在就新建文件夹
print('新建文件夹')
os.mkdir(flie)
return flie#返回文件夹路径
def down_img(self,data,name):
flie=self.mkdirs(name)
for title,img in data:
print('正在下载:',title)
print(img)
try:
# request.urlretrieve(img,flie+title+img[-4:])
down_img=requests.get(img,headers=headers,proxies=proxies,timeout=1).content
with open('{}{}.jpg'.format(flie,title),'wb')as f:
f.write(down_img)
except Exception as e:
pass
def run(self):
for page in range(self.star_age,self.end_page+1):
img_list=self.get_one_page_url(page)
for img in img_list:
data=self.get_one_data(img)
self.down_img(data,self.flie)
def main():
down=biying_img(1,3,'壁纸')
down.start()
down1=biying_img(7,10,'壁纸')
down1.start()
def main():
number = int(input('请输入要爬取的页数:'))
a = [i for i in range(0, number)]
step = 4
b = [a[i:i + step] for i in range(0, len(a), step)]
a1_max = max(b[0])
a1_min=min(b[0])
a2_max = max(b[1])
a2_min = min(b[1])
a3_max = max(b[2])
a3_min = min(b[2])
a4_max = max(b[3])
a4_min = min(b[4])
down=biying_img(a1_min,a1_max,'img')
down.start()
down1=biying_img(a2_min,a2_max,'img')
down1.start()
down2=biying_img(a3_min,a3_max,'img')
down2.start()
down3=biying_img(a4_min,a4_max,'img')
down3.start()
if __name__ == '__main__':
main()
上面的代码在写的时候还遇到一个问题就是有些图片的名字中间带有特殊符号,我在下载的时候忘了有这回事,然后程序就一直出错。不过已经解决这个问题了。