python如何抓取数据时失败_python爬虫实战之抓取异常如何处理?

1606378924512859.jpg

最近教大家用爬虫采集数据比较频繁,有些小伙伴在使用的时候难免出错,跟小编进行了交流之后也都成功解决了出错点。这里把大家容易出错的两种情况整理了出来,没有出错的小伙伴也可以一起看看,在查错的途中回顾与运用我们所学的知识点。下面就python爬虫抓取异常处理办法进行讲解。

可能在抓取的时候,某个账号突然就被封了,或者由于网络原因,某次请求失败了,该如何处理?对于前者,我们需要判断每次请求返回的内容是否符合预期,也就是看response url是否正常,看response content是否是404或者让你验证手机号等,对于后者,我们可以做一个简单的重试策略。处理这两种情况的代码如下@timeout_decorator

def get_page(url, user_verify=True, need_login=True):

"""

:param url: 待抓取url

:param user_verify: 是否为可能出现验证码的页面(ajax连接不会出现验证码,如果是请求微博或者用户信息可能出现验证码),否为抓取转发的ajax连接

:param need_login: 抓取页面是否需要登录,这样做可以减小一些账号的压力

:return: 返回请求的数据,如果出现404或者403,或者是别的异常,都返回空字符串

"""

crawler.info('本次抓取的url为{url}'.format(url=url))

count = 0

while count < max_retries:

if need_login:

# 每次重试的时候都换cookies,并且和上次不同,如果只有一个账号,那么就允许相同

name_cookies = Cookies.fetch_cookies()

if name_cookies is None:

crawler.warning('cookie池中不存在cookie,正在检查是否有可用账号')

rs = get_login_info()

# 选择状态正常的账号进行登录,账号都不可用就停掉celery worker

if len(rs) == 0:

crawler.error('账号均不可用,请检查账号健康状况')

# 杀死所有关于celery的进程

if 'win32' in sys.platform:

os.popen('taskkill /F /IM "celery*"')

else:

os.popen('pkill -f "celery"')

else:

crawler.info('重新获取cookie中...')

login.excute_login_task()

time.sleep(10)

try:

if need_login:

resp = requests.get(url, headers=headers, cookies=name_cookies[1], timeout=time_out, verify=False)

if "$CONFIG['islogin'] = '0'" in resp.text:

crawler.warning('账号{}出现异常'.format(name_cookies[0]))

freeze_account(name_cookies[0], 0)

Cookies.delete_cookies(name_cookies[0])

continue

else:

resp = requests.get(url, headers=headers, timeout=time_out, verify=False)

page = resp.text

if page:

page = page.encode('utf-8', 'ignore').decode('utf-8')

else:

continue

# 每次抓取过后程序sleep的时间,降低封号危险

time.sleep(interal)

if user_verify:

if 'unfreeze' in resp.url or 'accessdeny' in resp.url or 'userblock' in resp.url or is_403(page):

crawler.warning('账号{}已经被冻结'.format(name_cookies[0]))

freeze_account(name_cookies[0], 0)

Cookies.delete_cookies(name_cookies[0])

count += 1

continue

if 'verifybmobile' in resp.url:

crawler.warning('账号{}功能被锁定,需要手机解锁'.format(name_cookies[0]))

freeze_account(name_cookies[0], -1)

Cookies.delete_cookies(name_cookies[0])

continue

if not is_complete(page):

count += 1

continue

if is_404(page):

crawler.warning('url为{url}的连接不存在'.format(url=url))

return ''

except (requests.exceptions.ReadTimeout, requests.exceptions.ConnectionError, AttributeError) as e:

crawler.warning('抓取{}出现异常,具体信息是{}'.format(url, e))

count += 1

time.sleep(excp_interal)

else:

Urls.store_crawl_url(url, 1)

return page

crawler.warning('抓取{}已达到最大重试次数,请在redis的失败队列中查看该url并检查原因'.format(url))

Urls.store_crawl_url(url, 0)

return ''

这里大家把上述代码当一段伪代码读就行了,主要看看如何处理抓取时候的异常。因为如果贴整个用户抓取的代码,不是很现实,代码量有点大。

有同样抓取出错的小伙伴需要好好研究本篇文章,然后看自己是哪一种出错的类型再进行解决。更多Python学习指路:PyThon学习网教学中心。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值