python抓取数据时失败_爬取数据缺失的补坑,Python数据爬取的坑坑洼洼如何铲平...

渣渣业余选手讲解,关于爬取数据缺失的补坑,一点点关于Python数据爬取的坑坑洼洼如何铲平,个人的一些心得体会,还有结合实例的数据缺失的补全,几点参考,仅供观赏,如有雷同,那肯定是我抄袭的!

在使用Python爬取数据的过程中,尤其是用你自身电脑进行数据抓取,往往会有网络延迟,或者兼职网管拔插重启网络的情况发生,这是渣渣碰到的非常普遍的情况,当然推荐还是推荐使用服务器抓取数据。

当然这是比较常见和可控的网络爬取的异常,处理还是有不少方法或者说是方案的,也是这里着重谈谈的爬取数据缺失的补坑。

补坑一:timeou=x 的设置

requests抓取网页数据中,timeou属性建议一定要设置,一般为timeou=5,建议设置5s以上,如果你的网络差,或者抓取的网页服务器延迟比较厉害,比如国内访问国外网站服务器,建议设置10s以上!

为什么要设置imeou=x呢?

避免网络延迟,程序卡死,死机,连报错都不会出现,一直停滞在网页访问的过程中,这在 pyinstaller 打包的exe程序 使用中尤为常见!

超时(timeout)

为防止服务器不能及时响应,大部分发至外部服务器的请求都应该带着 timeout 参数。

在默认情况下,除非显式指定了 timeout 值,requests 是不会自动进行超时处理的。

如果没有 timeout,你的代码可能会挂起若干分钟甚至更长时间。

连接超时指的是在你的客户端实现到远端机器端口的连接时(对应的是 connect() ),Request 会等待的秒数。

一个很好的实践方法是把连接超时设为比 3 的倍数略大的一个数值,因为 TCP 数据包重传窗口 (TCP packet retransmission window) 的默认大小是 3。

在爬虫代理这一块我们经常会遇到请求超时的问题,代码就卡在哪里,不报错也没有requests请求的响应。

通常的处理是在requests.get()语句中加入timeout限制请求时间req = requests.get(url, headers=headers, proxies=proxies, timeout=5)

如果发现设置timeout=5后长时间不响应问题依然存在,可以将timeout里的参数细化

作出如下修改后,问题就消失了req = requests.get(url, headers=headers, proxies=proxies, timeout=(3,7))

timeout是用作设置响应时间的,响应时间分为连接时间和读取时间,timeout(3,7)表示的连接时间是3,响应时间是7,如果只写一个的话,就是连接和读取的timeout总和!

来源:CSDN博主「明天依旧可好」

补坑二:requests超时重试

requests访问重试的设置,你非常熟悉的错误信息中显示的是 read timeout(读取超时)报错。

超时重试的设置,虽然不能完全避免读取超时报错,但能够大大提升你的数据获取量,避免偶尔的网络超时而无法获取数据,避免你后期大量补坑数据。

一般超时我们不会立即返回,而会设置一个三次重连的机制。def gethtml(url):

i = 0

while i < 3:

try:

html = requests.get(url, timeout=5).text

return html

except requests.exceptions.RequestException:

i += 1

其实 requests 已经帮我们封装好了。(但是代码好像变多了...)import time

import requests

from requests.adapters import HTTPAdapter

s = requests.Session()

s.mount('http://', HTTPAdapter(max_retries=3))

s.mount('https://', HTTPAdapter(max_retries=3))

print(time.strftime('%Y-%m-%d %H:%M:%S'))

try:

r = s.get('http://www.google.com.hk', timeout=5)

return r.text

except requests.exceptions.RequestException as e:

print(e)

print(time.strftime('%Y-%m-%d %H:%M:%S'))

max_retries 为最大重试次数,重试3次,加上最初的一次请求,一共是4次,所以上述代码运行耗时是20秒而不是15秒2020-01-11 15:34:03

HTTPConnectionPool(host='www.google.com.hk', port=80): Max retries exceeded with url: / (Caused by ConnectTimeoutError(, 'Connection to www.google.com.hk timed out. (connect timeout=5)'))

2020-01-11 15:34:23

来源:大龄码农的Python之路

补坑三:urlretrieve()函数 下载图片

解决urlretrieve下载不完整问题且避免用时过长

下载文件出现urllib.ContentTooShortError且重新下载文件会存在用时过长的问题,而且往往会尝试好几次,甚至十几次,偶尔会陷入死循环,这种情况是非常不理想的。为此,笔者利用socket模块,使得每次重新下载的时间变短,且避免陷入死循环,从而提高运行效率。

以下为代码:import socket

import urllib.request

#设置超时时间为30s

socket.setdefaulttimeout(30)

#解决下载不完全问题且避免陷入死循环

try:

urllib.request.urlretrieve(url,image_name)

except socket.timeout:

count = 1

while count <= 5:

try:

urllib.request.urlretrieve(url,image_name)

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 > 5:

print("downloading picture fialed!")

来源:CSDN博主「山阴少年」

补坑四:time.sleep的使用

Python time sleep() 函数推迟调用线程的运行,可通过参数secs指秒数,表示进程挂起的时间。

某些网页请求过快,如果没有设置延迟1-2s,你是不会抓取到数据的!

当然这种情况还是比较少数!

想要顺利采集数据,不管什么方法,目的只有一个:记录下最后的状态,也就是你的抓取日志文件系统一定要完善!

附:

一次完整的数据补坑实例:

异常处理记录源码:s = requests.session()

s.mount('http://', HTTPAdapter(max_retries=3))

s.mount('https://', HTTPAdapter(max_retries=3))

try:

print(f">>> 开始下载 {img_name}图片 ...")

r=s.get(img_url,headers=ua(),timeout=15)

with open(f'{path}/{img_name}','wb') as f:

f.write(r.content)

print(f">>>下载 {img_name}图片 成功!")

time.sleep(2)

except requests.exceptions.RequestException as e:

print(f"{img_name}图片-{img_url}下载失败!")

with open(f'{path}/imgspider.txt','a+') as f:

f.write(f'{img_url},{img_name},{path}-下载失败,错误代码:{e}!\n')

下载图片报错:

异常文件记录数据:https://www.red-dot.org/index.php?f=65894&token=2aa10bf1c4ad54ea3b55f0f35f57abb4ba22cc76&eID=tx_solr_image&size=large&usage=overview,1_1_KRELL Automotive.jpg,2019Communication Design/Film & Animation-下载失败,错误代码:HTTPSConnectionPool(host='www.red-dot.org', port=443): Max retries exceeded with url: /index.php?f=65894&token=2aa10bf1c4ad54ea3b55f0f35f57abb4ba22cc76&eID=tx_solr_image&size=large&usage=overview (Caused by ReadTimeoutError("HTTPSConnectionPool(host='www.red-dot.org', port=443): Read timed out. (read timeout=15)"))!

https://www.red-dot.org/index.php?f=65913&token=8cf9f213e28d0e923e1d7c3ea856210502f57df3&eID=tx_solr_image&size=large&usage=overview,1_2_OLX – Free Delivery.jpg,2019Communication Design/Film & Animation-下载失败,错误代码:HTTPSConnectionPool(host='www.red-dot.org', port=443): Read timed out.!

https://www.red-dot.org/index.php?f=65908&token=426484d233356d6a1d4b8044f4994e1d7f8c141a&eID=tx_solr_image&size=large&usage=overview,1_3_Dentsu Aegis Network’s Data Training – Data Foundation.jpg,2019Communication Design/Film & Animation-下载失败,错误代码:HTTPSConnectionPool(host='www.red-dot.org', port=443): Max retries exceeded with url: /index.php?f=65908&token=426484d233356d6a1d4b8044f4994e1d7f8c141a&eID=tx_solr_image&size=large&usage=overview (Caused by NewConnectionError(': Failed to establish a new connection: [Errno 11004] getaddrinfo failed'))!

数据补坑思路:

第一步:搜索到异常记录文件,获取到文件路径

第二步:打开文件,获取到相关数据信息

第三步:重新下载图片信息,补充图片数据

几个关键点:

1.搜索异常文件,我这里是 imgspider.txt#搜索文件

def search(path,key):

"""

文件目录里 搜索想要查找的文件 输出文件所在路径

:param path: 想要搜索查询的目录

:param key: 搜索的文件关键字

:return: 返回目录

"""

key_paths=[]

#查看当前目录文件列表(包含文件夹)

allfilelist = os.listdir(path)

print(allfilelist)

for filelist in allfilelist:

if "." not in filelist:

filespath=os.path.join(path, filelist)

files= os.listdir(filespath)

print(files)

for file in files:

if "." not in file:

filepath=os.path.join(filespath, file)

file = os.listdir(filepath)

for file_name in file:

if key in file_name:

key_path=os.path.join(filepath,file_name)

print(f'找到文件,路径为{key_path}')

key_paths.append(key_path)

else:

if key in filelist:

key_path=os.path.join(path, filelist)

print(f'找到文件,路径为{key_path}')

key_paths.append(key_path)

return key_paths

这里只写到二级目录,其实可以改成递归函数调用,结合gui界面制作简易文件搜索工具助手!

搜索文件效果:

2.图片数据的处理

字符串分割函数 split

需要提取到三个信息,也就是异常记录里的信息内容

1.img_url:图片下载地址

2.img_name:图片名称

3.path:图片存储路径for data in datas:

img_data=data.split('-下载失败')[0]

img_url=img_data.split(',')[0]

img_name = img_data.split(',')[1]

path = img_data.split(',')[2]

print(img_name,img_url,path)

补坑效果:

附完整源码:# -*- coding: utf-8 -*-

#python3.7

# 20200111 by 微信:huguo00289

import os,time,requests

from fake_useragent import UserAgent

from requests.adapters import HTTPAdapter #引入 HTTPAdapter 库

#构成协议头

def ua():

ua=UserAgent()

headers={"User-Agent":ua.random}

return headers

#搜索文件

def search(path,key):

"""

文件目录里 搜索想要查找的文件 输出文件所在路径

:param path: 想要搜索查询的目录

:param key: 搜索的文件关键字

:return: 返回目录

"""

key_paths=[]

#查看当前目录文件列表(包含文件夹)

allfilelist = os.listdir(path)

print(allfilelist)

for filelist in allfilelist:

if "." not in filelist:

filespath=os.path.join(path, filelist)

files= os.listdir(filespath)

print(files)

for file in files:

if "." not in file:

filepath=os.path.join(filespath, file)

file = os.listdir(filepath)

for file_name in file:

if key in file_name:

key_path=os.path.join(filepath,file_name)

print(f'找到文件,路径为{key_path}')

key_paths.append(key_path)

else:

if key in filelist:

key_path=os.path.join(path, filelist)

print(f'找到文件,路径为{key_path}')

key_paths.append(key_path)

return key_paths

#获取图片下载失败的文件记录路径

def get_pmimgspider():

img_paths=[]

key = "imgspider"

categorys = [

"Advertising", "Annual Reports", "Apps", "Brand Design & Identity", "Brands", "Corporate Design & Identity",

"Fair Stands", "Film & Animation", "Illustrations", "Interface & User Experience Design",

"Online", "Packaging Design", "Posters", "Publishing & Print Media", "Retail Design", "Sound Design",

"Spatial Communication", "Typography", "Red Dot_Junior Award",

]

for category in categorys:

path = f'2019Communication Design/{category}'

key_paths = search(path, key)

img_paths.extend(key_paths)

print(img_paths)

return img_paths

#下载图片

def get_img(img_name,img_url,path):

s = requests.session()

s.mount('http://', HTTPAdapter(max_retries=3))

s.mount('https://', HTTPAdapter(max_retries=3))

try:

print(f">>> 开始下载 {img_name}图片 ...")

r=s.get(img_url,headers=ua(),timeout=15)

with open(f'{path}/{img_name}','wb') as f:

f.write(r.content)

print(f">>>下载 {img_name}图片 成功!")

time.sleep(2)

except requests.exceptions.RequestException as e:

print(f"{img_name}图片-{img_url}下载失败!")

with open(f'{path}/imgspider.txt','a+') as f:

f.write(f'{img_url},{img_name},{path}-下载失败,错误代码:{e}!\n')

def main2():

img_paths = get_pmimgspider()

for img_path in img_paths:

print(img_path)

with open(img_path) as f:

datas = f.readlines()

print(datas)

for data in datas:

img_data=data.split('-下载失败')[0]

img_url=img_data.split(',')[0]

img_name = img_data.split(',')[1]

path = img_data.split(',')[2]

print(img_name,img_url,path)

get_img(img_name, img_url, path)

if __name__=="__main__":

main2()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/349385.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于总决赛

可以将变量声明为final。 最终变量只能分配一次。 如果分配了最终变量&#xff0c;则将导致编译时错误&#xff0c;除非在分配前立即将其绝对取消分配。 分配任何最终变量后&#xff0c;将永远无法对其进行更改。 如果变量引用任何对象的任何实例&#xff0c;它将继续引用相同的…

java中void_关于java中void的用法?

阿波罗的战车void除了说明该方法没有返回值外&#xff0c;还有什么作用呢&#xff1f;构造方法同样也是没有返回值的&#xff0c;那它和void方法有什么区别呢&#xff1f;构造方法与方法又有什么区别&#xff1f;用具象的实物来表现的话三者有何种关系呢&#xff1f;id 除了说明…

卷积神经网络mnist手写数字识别代码_搭建经典LeNet5 CNN卷积神经网络对Mnist手写数字数据识别实例与注释讲解,准确率达到97%...

LeNet-5卷积神经网络是最经典的卷积网络之一&#xff0c;这篇文章就在LeNet-5的基础上加入了一些tensorflow的有趣函数&#xff0c;对LeNet-5做了改动&#xff0c;也是对一些tf函数的实例化笔记吧。环境 Pycharm2019Python3.7.6tensorflow 2.0 话不多说&#xff0c;先放完整源码…

glassfish_多种监视和管理GlassFish 3的方法

glassfishGlassFish 3支持多种监视和管理方法。 在本文中&#xff0c;我将简要介绍GlassFish提供的管理&#xff0c;监视和管理方法。 GlassFish管理控制台 GlassFish基于Web的管理控制台GUI可能是GlassFish管理最著名的界面。 默认情况下&#xff0c;运行GlassFish后&#xf…

java 阻塞锁_Java实现锁、公平锁、读写锁、信号量、阻塞队列、线程池等常用并发工具...

锁的实现锁的实现其实很简单&#xff0c;主要使用Java中synchronized关键字。public class Lock {private volatile boolean isLocked false;private Thread lockingThread null;public synchronized void lock() throws InterruptedExpection {while(isLocked){wait();}isLo…

flask-mail异步发送邮件_SpringBoot 2.0 集成 JavaMail ,实现异步发送邮件

一、JavaMail的核心API1、API功能图解2、API说明(1)、Message 类:javax.mail.Message 类是创建和解析邮件的一个抽象类子类javax.mail.internet.MimeMessage &#xff1a;表示一份电子邮件。 发送邮件时&#xff0c;首先创建出封装了邮件数据的 Message 对象&#xff0c; 然后把…

Java 9中什么是私有的?

在进行面试时&#xff0c;我发现大多数应聘者都不知道Java中的private修饰符真正意味着什么。 他们知道一些足以进行日常编码的事情&#xff0c;但还远远不够。 这不成问题。 足够了解就足够了。 但是&#xff0c;了解Java的一些内部工作仍然很有趣。 在极少数情况下&#xff0…

python国际象棋ai程序_用Python编写一个国际象棋AI程序

最近我用Python做了一个国际象棋程序并把代码发布在Github上了。这个代码不到1000行&#xff0c;大概20%用来实现AI。在这篇文章中我会介绍这个AI如何工作&#xff0c;每一个部分做什么&#xff0c;它为什么能那样工作起来。你可以直接通读本文&#xff0c;或者去下载代码&…

java switch case怎么判断范围_【转】Java期末复习攻略!

期末19年就这样要过去了&#xff0c;终于到了小时候作文里的未来呢&#xff01;然而&#xff0c;期末考试也随之来临了。不知大家“预习”的怎么样呢&#xff1f; 期末复习资料的放送快接近尾声了下面康康学长学姐们怎么教你们打java这个boss(下面是java大佬给大家的复习建议以…

java list 去重复元素_java List去掉重复元素的几种方式

使用LinkedHashSet删除arraylist中的重复数据(有序)List words Arrays.asList("a","b","b","c","c","d");HashSet setnew LinkedHashSet<>(words);for(String word:set){System.out.println(word);}使用Has…

spring aop示例_Spring JpaRepository示例(内存中)

spring aop示例这篇文章描述了一个使用内存中HSQL数据库的简单Spring JpaRepository示例。 该代码示例可从GitHub的Spring-JpaRepository目录中获得。 它基于带有注释的Spring-MVC-示例和此处提供的信息 。 JPA资料库 在此示例中&#xff0c;我们实现了一个虚拟bean&#xff1…

python人工智能入门优达视频_机器学习:优达教你搭建Python 环境的正确姿势

原标题&#xff1a;机器学习:优达教你搭建Python 环境的正确姿势为机器学习搭建好 Python 环境听起来简单&#xff0c;但有时候坑还不少。如果此前没有配置过类似的环境&#xff0c;很可能会苦苦折腾各种命令好几个小时。可是我明明只是想马上搞起来我的机器学习&#xff01; 在…

java web登录状态保持_java web用于保持状态的4种方法

方法一&#xff1a;网址重写通过在url地址后面添加若干的token作为查询字符串来实现。token的值一般为 键值url?key1value1&key2value2&...&keynvaluenurl与token之间需要用?分开&#xff0c;两个token之间则是需要用一个&符号隔开。此方法适用于token不需要…

python天天向上续2_2019/2/12 Python今日收获

Python day12——025&#xff0c;026字典&#xff1a;当索引不好用时 1.字典&#xff1a;python唯一的一个映射类型。用键值对存储数据&#xff0c;他的标志是大括号。一个键值组合叫一个项。键的类型既可以是字符串类型也可以是整形也可以是浮点型。 如&#xff1a;dict{1:one…

python生成矩阵_如何在Python中生成矩阵?

你的问题的答案取决于你的学习目标是什么。如果您试图让矩阵“点击”以便以后使用它们&#xff0c;我建议您查看一个Numpyarray&#xff0c;而不是一个列表列表。这将使您可以轻松地分割行、列和子集。只要试着从列表中获取一个列&#xff0c;你就会感到沮丧。 使用列表列表作为…

java ee cdi_Java EE CDI ConversationScoped示例

java ee cdi在本教程中&#xff0c;我们将向您展示如何在Web应用程序中创建和使用ConversationScoped Bean。 在CDI中&#xff0c;bean是定义应用程序状态和/或逻辑的上下文对象的源。 如果容器可以根据CDI规范中定义的生命周期上下文模型来管理其实例的生命周期&#xff0c;则…

js input 自动换行_深入Slate.js - 拯救 ContentEditble

我们是钉钉的文档协同团队&#xff0c;我们在做一些很有意义的事情&#xff0c;其中之一就是自研的文字编辑器。为了把自研文字编辑器做好&#xff0c;我们调研了开源社区各种优秀编辑器&#xff0c;Slate.js 是其中之一&#xff08;实际上&#xff0c;自研文字编辑器前&#x…

java main 如何不退出_为什么java main主线程退出了子线程还能运行;golang main结束所有协程都被结束了...

最近看golang main函数结束&#xff0c;所有协程都被结束了结论是这样&#xff1a;A不是main程的情况下&#xff0c;在A程里开启B程&#xff0c;A程执行完&#xff0c;A程return之后&#xff0c;B程不受影响&#xff0c;不会挂掉。所有子协程与main程同级的&#xff0c;与main程…

安全点

安全点 Java应用程序中有两个逻辑线程组&#xff1a; 应用程序线程执行应用程序逻辑 执行GC的线程 在执行诸如堆压缩之类的操作时&#xff0c;GC线程会四处移动一些对象&#xff0c;并且这些对象不能被任何应用程序线程使用&#xff0c;因为它们的物理位置可能会发生变化。 …

printf 地址_C程序显示主机名和IP地址

查找本地计算机的主机名和IP地址的方法有很多。这是使用C程序查找主机名和IP地址的简单方法。我们将使用以下功能&#xff1a;gethostname() &#xff1a;gethostname函数检索本地计算机的标准主机名。gethostbyname() &#xff1a;gethostbyname函数从主机数据库中检索与主机名…