如果不是要求速度的话还是用一下time.sleep()吧,我刚刚爬的时候好像是被封了,用浏览器也打不开斗图啦网站,过了几分钟才能继续访问,这个还是要注意一下。
我本来是想试一下代理ip的,但免费的ip真的是不行,付费的又不想出这个 钱,想想还是算了。
import requests,time,os,re
import threading
from lxml import etree
from queue import Queue
start = time.time()
# 获取数据
class Getdata(threading.Thread):
def __init__(self,page_queue,get_queue):
super(Getdata,self).__init__()
self.page_queue = page_queue
self.get_queue = get_queue
# threading.thread 有 run 方法,会从run()方法开始执行函数
def run(self):
while True:
if self.page_queue.empty():
break
else:
# 从队列中获取 主 url
url = self.page_queue.get()
self.request_data(url)
def request_data(self,url):
s = requests.Session()
# 在网页中右击->检查->netmwork->刷新网页,在network中随便点击一个文件,查看hearders
# 设置一个小的反反爬虫:设置请求头
headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
}
resp = s.get(url,headers=headers)
time.sleep(1)
text = resp.text
# ,使用xpath需要解析网页源码
html = etree.HTML(text)
# xpath相关语法,获取标签下的内容
divs = html.xpath("//div[@class='page-content text-center']")
for div in divs:
a_s = div.xpath("//a[@class='col-xs-6 col-sm-3']")
for a in a_s:
# 获取图片的 url
img = a.xpath("./img/@data-original")[0]
#获得图片后缀名,.png .gif等,创建文件名时使用
hz = img.split('.')[-1]
filename = a.xpath("./img/@alt")[0] + '.' +hz
# 调用处理file的方法
filename =self.file(filename)
# 由图片url获取图片数据
img_data = s.get(img,headers=headers)
data = img_data.content
# 将图片数据和文件名放到线程中
time.sleep(1)
self.get_queue.put((filename,data))
def file(self,filename):
# 如果该文件夹不存在则创建,存在则什么都不做
os.makedirs("斗图",exist_ok=True)
# 将文件放到 斗图文件夹下
filename_1 = os.path.join("斗图",filename)
# 使用正则表达式将名字中某些符号换成空白字符,
# 以免文件因名字,而不能创建成功
filename = re.sub(r'[,@??!!:。]', '', filename_1)
return filename
# 下载数据
class D_data(threading.Thread):
def __init__(self,page_queue,get_queue):
super(D_data, self).__init__()
self.page_queue = page_queue
self.get_queue = get_queue
def run(self):
while True:
#当两个队列都空了,就退出
if self.get_queue.empty() and self.page_queue.empty():
break
else:
filename, data = self.get_queue.get()
print(filename)
# 保存图片
with open(filename,"wb") as fp:
fp.write(data)
def main():
# 创建两个队列,放置线程
page_queue = Queue(4)
get_queue = Queue(1000)
# 获取前四页的内容
for x in range(1,5):
url = "http://www.doutula.com/photo/list/?page={}".format(x)
page_queue.put(url)
t1 = Getdata(page_queue,get_queue)
# 启动
t1.start()
t2 = D_data(page_queue,get_queue)
t2.start()
if __name__ == '__main__':
main()
end = time.time()
print(end-start)