Как использовать запросы на парсинг веб-страниц? - PullRequest
1 голос
/ 10 июля 2020

Это моя первая попытка выполнить парсинг в Интернете, и я следую руководству. Пока что у меня есть код:

from bs4 import BeautifulSoup
import requests

source = requests.get('https://www.usnews.com/best-colleges/rankings/national-universities')

soup = BeautifulSoup(source, 'lxml')

print(soup.prettify())

Однако я получаю сообщение об ошибке:


Traceback (most recent call last):
  File "/Users/alanwen/Desktop/webscrape.py", line 4, in <module>
    source = requests.get('https://www.usnews.com/best-colleges/rankings/national-universities')
  File "/Users/alanwen/Library/Python/2.7/lib/python/site-packages/requests/api.py", line 76, in get
    return request('get', url, params=params, **kwargs)
  File "/Users/alanwen/Library/Python/2.7/lib/python/site-packages/requests/api.py", line 61, in request
    return session.request(method=method, url=url, **kwargs)
  File "/Users/alanwen/Library/Python/2.7/lib/python/site-packages/requests/sessions.py", line 530, in request
    resp = self.send(prep, **send_kwargs)
  File "/Users/alanwen/Library/Python/2.7/lib/python/site-packages/requests/sessions.py", line 643, in send
    r = adapter.send(request, **kwargs)
  File "/Users/alanwen/Library/Python/2.7/lib/python/site-packages/requests/adapters.py", line 529, in send
    raise ReadTimeout(e, request=request)
requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='www.usnews.com', port=443): Read timed out. (read timeout=None)
[Finished in 25.1s with exit code 1]
[shell_cmd: python -u "/Users/alanwen/Desktop/webscrape.py"]
[dir: /Users/alanwen/Desktop]
[path: /Library/Frameworks/Python.framework/Versions/3.8/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/share/dotnet:/opt/X11/bin:~/.dotnet/tools:/Library/Frameworks/Mono.framework/Versions/Current/Commands]

Ответы [ 3 ]

0 голосов
/ 10 июля 2020

Эта страница нуждается в заголовке User-Agent для распознавания браузером. Он может быть даже неполным Mozilla/5.0, но requests обычно отправляет python-requests/2.23.0.

Без правильного заголовка этот сервер блокирует соединение, и через некоторое время вы можете получить сообщение с "timedout", потому что requests не может дольше ждать данных с сервера.

BTW: BeautifulSoup требуется source.text или source.content не source (что является requests объектом).

Рабочий код:

import requests
from bs4 import BeautifulSoup

url = 'https://www.usnews.com/best-colleges/rankings/national-universities'
headers = {'User-Agent': 'Mozilla/5.0'}

r = requests.get(url, headers=headers)

soup = BeautifulSoup(r.content, 'lxml')

print(soup.prettify())

Кстати: Используя страницу https://httpbin.org/, вы можете проверить, что вы отправляете на сервер

import requests

r = requests.get('https://httpbin.org/get')
#r = requests.post('https://httpbin.org/post')
#r = requests.get('https://httpbin.org/ip')
#r = requests.get('https://httpbin.org/user-agent')

print( r.text )
#print( r.content )
#print( r.json() )

, вы также можете проверить (если вы используете url с /get или /post)

print( r.json()['headers']['User-Agent'] ) 

или вы можете проверить объект запросов

print( r.request.headers['User-Agent'] )

, и вы увидите User-Agent

{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.23.0", 
    "X-Amzn-Trace-Id": "Root=1-5f07c942-067f5b72784a207b31e76ce4"
  }, 
  "origin": "83.23.22.221", 
  "url": "https://httpbin.org/get"
}

python-requests/2.23.0

python-requests/2.23.0
0 голосов
/ 10 июля 2020

этот веб-сайт в первый раз веб-парсинг - плохой выбор, потому что этот веб-сайт не является обычным сайтом для парсинга, я думаю, вы должны его использовать селен :

from selenium import webdriver
from bs4 import BeautifulSoup
import pandas as pd
import os
import time


chromedriver = "driver/chromedriver"
os.environ["webdriver.chrome.driver"] = chromedriver
driver = webdriver.Chrome(chromedriver)

url = 'https://www.usnews.com/best-colleges/rankings/national-universities'

driver.get(url)
source = driver.page_source

soup = BeautifulSoup(source, 'lxml')

print(soup.prettify())
0 голосов
/ 10 июля 2020

Вы должны добавить .text в конце строки запроса, чтобы получить фактический исходный код веб-страницы. Вместо

from bs4 import BeautifulSoup
import requests

source = requests.get('https://www.usnews.com/best-colleges/rankings/national-universities')

soup = BeautifulSoup(source, 'lxml')

print(soup.prettify())

Do

from bs4 import BeautifulSoup
import requests

source = requests.get('https://www.usnews.com/best-colleges/rankings/national-universities').text

soup = BeautifulSoup(source, 'lxml')

print(soup.prettify())

Если вы получите сообщение об ошибке bs4.FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library? установите модуль lxml через pip

...