Python 刮取多个页面时经常出现HTTP错误413
我在Wykop.pl(“波兰的Reddit”)上搜索我感兴趣的关键字时返回的多个页面,通过循环浏览这些页面,从中删除帖子。我编写了一个循环来迭代每个页面的目标内容;但是,循环将在某些页面终止(一致),错误为“HTTP错误413:请求实体太大” 我试图逐个刮取有问题的页面,但相同的错误消息不断出现。为了解决这个问题,我不得不手动设置范围来收集数据,但代价是丢失了大量数据,我想知道是否有Pythonic解决方案来处理这个错误。我还尝试了更长的暂停时间,因为可能我有发送太多请求的风险,但事实似乎并非如此Python 刮取多个页面时经常出现HTTP错误413,python,pandas,web-scraping,beautifulsoup,runtime-error,Python,Pandas,Web Scraping,Beautifulsoup,Runtime Error,我在Wykop.pl(“波兰的Reddit”)上搜索我感兴趣的关键字时返回的多个页面,通过循环浏览这些页面,从中删除帖子。我编写了一个循环来迭代每个页面的目标内容;但是,循环将在某些页面终止(一致),错误为“HTTP错误413:请求实体太大” 我试图逐个刮取有问题的页面,但相同的错误消息不断出现。为了解决这个问题,我不得不手动设置范围来收集数据,但代价是丢失了大量数据,我想知道是否有Pythonic解决方案来处理这个错误。我还尝试了更长的暂停时间,因为可能我有发送太多请求的风险,但事实似乎并非如
from time import sleep
from random import randint
import requests
from requests import get
from bs4 import BeautifulSoup
from mtranslate import translate
from IPython.core.display import clear_output
from mtranslate import translate
posts = []
votes = []
dates = []
images = []
users = []
start_time = time()
requests = 0
pages = [str(i) for i in range(1,10)]
for page in pages:
url = "https://www.wykop.pl/szukaj/wpisy/smog/strona/" + page + "/"
response = get(url)
# Pause the loop
sleep(randint(8,15))
# Monitor the requests
requests += 1
elapsed_time = time() - start_time
print('Request:{}; Frequency: {} requests/s'.format(requests, requests/elapsed_time))
clear_output(wait = True)
# Throw a warning for non-200 status codes
if response.status_code != 200:
warn('Request: {}; Status code: {}'.format(requests, response.status_code))
# Break the loop if the number of requests is greater than expected
if requests > 10:
warn('Number of requests was greater than expected.')
break
soup = BeautifulSoup(response.text, 'html.parser')
results = soup.find_all('li', class_="entry iC")
for result in results:
# Error handling
try:
post = result.find('div', class_="text").text
post = translate(post,'en','auto')
posts.append(post)
date = result.time['title']
dates.append(date)
vote = result.p.b.span.text
vote = int(vote)
votes.append(vote)
user = result.div.b.text
users.append(user)
image = result.find('img',class_='block lazy')
images.append(image)
except AttributeError as e:
print(e)
如果我可以一次运行所有脚本,我会将范围设置为1到163(因为我已经有163页的文章结果提到了我感兴趣的关键字)。因此,我不得不设置较小的范围以增量方式收集数据,但同样是以丢失数据页为代价的
作为一种应急措施,我还可以从桌面上指定的有问题的页面中删除下载的html文档。您可能遇到了某种IP地址限制。在运行脚本时,它对我来说很好,没有任何速率限制(目前)。不过,我建议您使用
requests.Session()
(您需要更改requests
变量,否则它会覆盖导入)。这有助于减少可能的内存泄漏问题
例如:
from bs4 import BeautifulSoup
from time import sleep
from time import time
from random import randint
import requests
posts = []
votes = []
dates = []
images = []
users = []
start_time = time()
request_count = 0
req_sess = requests.Session()
for page_num in range(1, 100):
response = req_sess.get(f"https://www.wykop.pl/szukaj/wpisy/smog/strona/{page_num}/")
# Pause the loop
#sleep(randint(1,3))
# Monitor the requests
request_count += 1
elapsed_time = time() - start_time
print('Page {}; Request:{}; Frequency: {} requests/s'.format(page_num, request_count, request_count/elapsed_time))
#clear_output(wait = True)
# Throw a warning for non-200 status codes
if response.status_code != 200:
print('Request: {}; Status code: {}'.format(requests, response.status_code))
print(response.headers)
# Break the loop if the number of requests is greater than expected
#if requests > 10:
# print('Number of requests was greater than expected.')
# break
soup = BeautifulSoup(response.text, 'html.parser')
results = soup.find_all('li', class_="entry iC")
for result in results:
# Error handling
try:
post = result.find('div', class_="text").text
#post = translate(post,'en','auto')
posts.append(post)
date = result.time['title']
dates.append(date)
vote = result.p.b.span.text
vote = int(vote)
votes.append(vote)
user = result.div.b.text
users.append(user)
image = result.find('img',class_='block lazy')
images.append(image)
except AttributeError as e:
print(e)
给出了以下输出:
第1页;请求:1;频率:1.24613732973911请求/秒
第2页;请求:2;频率:1.3021880233774552请求/秒
第3页;请求:3;频率:1.2663757427416629请求/秒
第4页;请求:4;频率:1.1807827876080845请求/秒
.
.
.
第96页;请求:96;频率:0.888853607003809请求/秒
第97页;请求:97;频率:0.8891876183362001请求/秒
第98页;请求:98;频率:0.8801819672809请求/秒
第99页;请求:99;频率:0.8900784741536467请求/秒
当我开始使用更高的页码时,这也很好。理论上,当您获得413错误状态代码时,它现在应该显示响应头。根据,服务器应该返回一个
Retry After
头字段,您可以使用该字段确定在下一个请求之前要退出多长时间。您可能遇到了某种IP地址限制。在运行脚本时,它对我来说很好,没有任何速率限制(目前)。不过,我建议您使用requests.Session()
(您需要更改requests
变量,否则它会覆盖导入)。这有助于减少可能的内存泄漏问题
例如:
from bs4 import BeautifulSoup
from time import sleep
from time import time
from random import randint
import requests
posts = []
votes = []
dates = []
images = []
users = []
start_time = time()
request_count = 0
req_sess = requests.Session()
for page_num in range(1, 100):
response = req_sess.get(f"https://www.wykop.pl/szukaj/wpisy/smog/strona/{page_num}/")
# Pause the loop
#sleep(randint(1,3))
# Monitor the requests
request_count += 1
elapsed_time = time() - start_time
print('Page {}; Request:{}; Frequency: {} requests/s'.format(page_num, request_count, request_count/elapsed_time))
#clear_output(wait = True)
# Throw a warning for non-200 status codes
if response.status_code != 200:
print('Request: {}; Status code: {}'.format(requests, response.status_code))
print(response.headers)
# Break the loop if the number of requests is greater than expected
#if requests > 10:
# print('Number of requests was greater than expected.')
# break
soup = BeautifulSoup(response.text, 'html.parser')
results = soup.find_all('li', class_="entry iC")
for result in results:
# Error handling
try:
post = result.find('div', class_="text").text
#post = translate(post,'en','auto')
posts.append(post)
date = result.time['title']
dates.append(date)
vote = result.p.b.span.text
vote = int(vote)
votes.append(vote)
user = result.div.b.text
users.append(user)
image = result.find('img',class_='block lazy')
images.append(image)
except AttributeError as e:
print(e)
给出了以下输出:
第1页;请求:1;频率:1.24613732973911请求/秒
第2页;请求:2;频率:1.3021880233774552请求/秒
第3页;请求:3;频率:1.2663757427416629请求/秒
第4页;请求:4;频率:1.1807827876080845请求/秒
.
.
.
第96页;请求:96;频率:0.888853607003809请求/秒
第97页;请求:97;频率:0.8891876183362001请求/秒
第98页;请求:98;频率:0.8801819672809请求/秒
第99页;请求:99;频率:0.8900784741536467请求/秒
当我开始使用更高的页码时,这也很好。理论上,当您获得413错误状态代码时,它现在应该显示响应头。根据,服务器应该返回一个
Retry After
头字段,您可以使用该字段确定在下一个请求之前要退出多长时间。好,下面是要点:
413错误与Wykop无关,Wykop是一个需要删除的网站,但与mtranslate软件包有关,该软件包依赖于Google Translate的API。在我最初的代码中,当Wykop被删除时,它将文章从波兰语翻译成英语。然而,谷歌翻译API对每个用户的限制是每100秒100000个字符。因此,当代码到达第13页时,mtranslate达到了Google Translate的请求限制。因此,Martin的解决方案可以在禁用translate函数的情况下很好地抓取数据
当我使用模块翻译存储在数据帧中的帖子时,我得出了这个结论,因为我在翻译循环的8%处遇到了相同的错误。好的,下面是一个问题: 413错误与Wykop无关,Wykop是一个需要删除的网站,但与mtranslate软件包有关,该软件包依赖于Google Translate的API。在我最初的代码中,当Wykop被删除时,它将文章从波兰语翻译成英语。然而,谷歌翻译API对每个用户的限制是每100秒100000个字符。因此,当代码到达第13页时,mtranslate达到了Google Translate的请求限制。因此,Martin的解决方案可以在禁用translate函数的情况下很好地抓取数据
我是在使用模块翻译数据帧中存储的帖子时得出这个结论的,因为我在翻译循环的8%处遇到了相同的错误。缺少BS4导入,朋友!很可能你只是在粘贴时出错了..还有!内存泄漏是请求库中非常常见的问题。您应该研究异步请求来处理它。更好的是,开始使用刮痧!缺少BS4导入,朋友!很可能你只是在粘贴时出错了..还有!内存泄漏是请求库中非常常见的问题。您应该研究异步请求来处理它。更好的是,开始使用刮痧!嗨,马丁;工作得很有魅力!有趣的是: