1,首先,就开了两个线程,下载速度超级快,不知道是不是网速的原因。
2,q.put(),不能传入两个值的问题,我解决了。我把两个值装进一个字典当中即可。
然后从字典当中提取出两个值就可以了!就这么一个小小的思路,让我成功了。
3,图片360张,只能下载成功330张。目前尚不清楚该如何优化,这个版本就先发布了。
4,用的是queue队列模块。看的是老男孩的教程,非常详细容易懂,收货非常大!
'''
1,http://www.doutula.com/article/list/?page=2
2,网站几乎没有任何反爬虫限制机制,加一个header就可以爬取,很easy。
3,但是有个问题,程序有时候运行的很快,只需要1.4s。有时候非常慢,需要95s,不知道是什么原因。。。
百度了一下,爬虫最快1.4s就爬取了,说明不是我爬虫问题。是网络方面问题。
结果,到后期,反而没办法爬取数据了!是反爬机制?还是什么原因???
4,访问的话,隔一段时间勉强还能用。但是下载图片就不行了,明显提示我:urllib.error.HTTPError: HTTP Error 403: Forbidden
发现了一个问题,我用代理ip的话,可以正常访问,但是没有办法下载了,应该是屏蔽了我下载功能,但是可以正常访问。
正常访问还是很快的!--用免费代理ip即可。
5,弄明白了。 request.urlretrieve 这里,必须加上header请求头,不然服务器一般都会拒绝的。具体加上请求头也很简单。
其次, request.urlretrieve 中,参数我写错了。
request.urlretrieve(url=i["图片链接"],filename='images/'+i["图片名称"]+i["图片格式"])---url和filename必须这么写才行。
其次,images文件夹必须先手动创建好才可以。
6,下载进度到80%的时候。就提示了新错误。
urllib.error.ContentTooShortError: <urlopen error retrieval incomplete: got only 21032 out of 90495 bytes>
不明白啥意思。。百度之后是:urllib.urlretrieve()下载不完全的问题
解决办法:https://blog.csdn.net/Innovation_Z/article/details/51106601
7,try--except被我调试好了之后,就一直循环卡在那里。应该修改一下,跳过。
8,RuntimeError: can't start new thread, 测试的时候线程开得太多了,导致软件开始,不再能够被处理,卡死。
'''
import requests
import re, time
from urllib import request
import os
import socket
import threading
from queue import Queue
items = []
num = 0
gLock = threading.Lock()
q = Queue(100)
def parse_page(url):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36',
#'Cookie': '__cfduid=dbf4a58fd52d6bbff2edd84c087f103de1556492495; UM_distinctid=16a662eaa6a3b0-0d88093cd8e4bb-5f1d3a17-e1000-16a662eaa6b1bf; _ga=GA1.2.1199216971.1556492496; _gid=GA1.2.610348230.1556492496; yjs_id=c9f5eea2c4cb5dbd197d298576d15289; ctrl_time=1; XSRF-TOKEN=eyJpdiI6ImZGdjRodFNHZ2pSNW9TaHhUY3ptTXc9PSIsInZhbHVlIjoibFRnNnZyaHhoRmhmTU5wZWJtNWEwc0NSRVwvRDdQUnFrdEdBODBKbDlRWFBzbk9seHZkVk44NkFreDNicEJHODgiLCJtYWMiOiI1MmFmNTBkYzRiNDI1NWFlMjc1MzIxNmU3ODMwZjcyYzE2ZjE5NTBhMTk2ZWYzNTJmYjU4NmZjNTM5ZDA3ODJkIn0%3D; doutula_session=eyJpdiI6IlJGVUVFZlhNcmx6UEorTFwvMVVpczRnPT0iLCJ2YWx1ZSI6IjNvbHdXaTFjRGVrZHB1TllreU0zbUIyZGExWXZ0NjM1YlE5eGlRbnBtcUpzNHhhaXdoa2ZmQ1c0S3NOR0tHeUIiLCJtYWMiOiIxMTQ3NDNjZTFlMmJiMTFiMTM5ZjRmNWY0MjY0ZDdiNjQyYzVjMTNjNTY3NmJjNDYyYmJlMmQyYTE5MjIwZWIxIn0%3D; BAIDU_SSP_lcr=https://www.baidu.com/link?url=fdTOuTAcVkFuILyrtze2YFKLVs2tnCDOrM9AR06gWoZwMaJTqabjO-Y1ZiOlH-wo&wd=&eqid=fb0bf5a500066595000000025cc6430b; CNZZDATA1256911977=1763119621-1556491399-null%7C1556496681; _gat=1'
}
# proxy = {
# 'http':'110.52.235.95:9999'
# }
response = requests.get(url, headers=headers)
print(response.status_code)
text = response.text
#print(text)
global items
global num
url_links = re.findall(r'data-original="(.*?)" data-backup', text, re.DOTALL)
#print(url_links)
titles = re.findall(r'data-original=".*?" data-backup=".*?" alt="(.*?)"', text, re.DOTALL)
#print(titles)
for link,title in zip(url_links,titles):
title = re.sub(r'[!!,??,。.]+','',title) #标题里一些乱七八糟的符号都过滤掉。用正则sub函数还是很好用的!
geshi = os.path.splitext(link)[1] #返回的是每个链接后面的图片格式:例如 .jpeg
data={
"图片链接":link,
"图片名称":title,
"图片格式": geshi
}
# print(data)
items.append(data)
num +=1
print("运行中。。")
#print(items)
def auto_down(): #想用这个try-except函数,但是系统总是提示urllib没有ContentTooShortError,目前没办法用。
while 1:
# 设置超时时间为30s
opener = request.build_opener()
opener.addheaders = [('User-Agent',
'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36')]
request.install_opener(opener)
socket.setdefaulttimeout(2)
data = q.get()
try:
request.urlretrieve(url=data["url"],filename=data["filename"]) #成功了。
except socket.timeout:
count = 1
while count <= 3:
try:
request.urlretrieve(url=data["url"],filename=data["filename"])
break
except socket.timeout:
err_info = 'Reloading for %d time' % count if count == 1 else 'Reloading for %d times' % count
print(err_info)
count += 1
if count > 3:
print("downloading picture fialed!")
def get_items():
url = "http://www.doutula.com/article/list/?page=2"
for x in range(1, 10):
url = "http://www.doutula.com/article/list/?page=%s" % x
parse_page(url) # 获取了所有页面的图片链接,整理好装进了items列表当中。
# parse_page(url)
print("已经下载了第%s个链接" % num)
print(items)
def set_value(q):
global items
for i in items:
url = i["图片链接"]
filename = 'images/' + i["图片名称"] + i["图片格式"]
data = {"url":url,"filename":filename}
q.put(data)
# time.sleep(3)
def main():
get_items() #获取一个大列表,列表中,都是字典。里面有自己想要的图片信息。
time_start = time.time()
t1 = threading.Thread(target=set_value, args=(q,))
t2 = threading.Thread(target=auto_down)
t3 = threading.Thread(target=auto_down)
t1.start()
t2.start()
t3.start()
#计算一下程序耗时。
time_end = time.time()
print('totally cost', time_end - time_start)
if __name__ == '__main__':
main()