如何使用Python抓取网站的多个页面?
Web Scraping 是一种使用计算机程序从网站中提取有用数据的方法,而无需手动进行。然后可以出于各种目的导出和分类组织这些数据。 Web Scraping 的一些常见用途是市场研究和分析网站、价格比较工具、搜索引擎、AI/ML 项目的数据收集等。
让我们深入研究并抓取一个网站。在本文中,我们将使用 GeeksforGeeks 网站并使用Python脚本提取主页上所有可用文章的标题。
如果您注意到,网站上有数以千计的文章,要提取所有文章,我们将不得不浏览所有页面,以免错过任何文章!
使用Python抓取网站的多个页面
现在,可能会出现各种情况,您可能希望从同一网站的多个页面或多个不同的 URL 获取数据,并且为每个网页手动编写代码是一项耗时且乏味的任务。此外,它违背了自动化的所有基本原则。呸!
为了解决这个确切的问题,我们将看到两种主要技术可以帮助我们从多个网页中提取数据:
- 同一个网站
- 不同的网址
方法:
该程序的方法将相当简单,并且以 POINT 格式更容易理解:
- 我们将导入所有必要的库。
- 设置我们的 URL字符串以使用请求库建立连接。
- 使用BeautifulSoup库的解析器从目标页面解析可用数据。
- 从目标页面,识别并提取包含对我们有价值的信息的类和标签。
- 使用循环为一页制作原型,然后将其应用于所有页面。
示例 1:循环遍历页码
大多数网站都有从 1 到 N 标记的页面。这使得我们可以很容易地遍历这些页面并从中提取数据,因为这些页面具有相似的结构。例如:
在这里,我们可以在 URL 的末尾看到页面详细信息。使用这些信息,我们可以轻松地创建一个for 循环,遍历任意数量的页面(通过将page/(i)/放在 URL字符串并迭代“ i ”直到 N )并从中抓取所有有用的数据。以下代码将使您更清楚地了解如何在Python使用For 循环来抓取数据。
Python
import requests
from bs4 import BeautifulSoup as bs
URL = 'https://www.geeksforgeeks.org/page/1/'
req = requests.get(URL)
soup = bs(req.text, 'html.parser')
titles = soup.find_all('div',attrs = {'class','head'})
print(titles[4].text)
Python
import requests
from bs4 import BeautifulSoup as bs
URL = 'https://www.geeksforgeeks.org/page/'
for page in range(1,10):
# pls note that the total number of
# pages in the website is more than 5000 so i'm only taking the
# first 10 as this is just an example
req = requests.get(URL + str(page) + '/')
soup = bs(req.text, 'html.parser')
titles = soup.find_all('div',attrs={'class','head'})
for i in range(4,19):
if page>1:
print(f"{(i-3)+page*15}" + titles[i].text)
else:
print(f"{i-3}" + titles[i].text)
Python
import requests
from bs4 import BeautifulSoup as bs
URL = ['https://www.geeksforgeeks.org','https://www.geeksforgeeks.org/page/10/']
for url in range(0,2):
req = requests.get(URL[url])
soup = bs(req.text, 'html.parser')
titles = soup.find_all('div',attrs={'class','head'})
for i in range(4, 19):
if url+1 > 1:
print(f"{(i - 3) + url * 15}" + titles[i].text)
else:
print(f"{i - 3}" + titles[i].text)
Python3
from random import randint
from time import sleep
print(randint(1,10))
Python3
from time import *
from random import randint
for i in range(0,3):
# selects random integer in given range
x = randint(2,5)
print(x)
sleep(x)
print(f'I waited {x} seconds')
Python3
import requests
from bs4 import BeautifulSoup as bs
from random import randint
from time import sleep
URL = 'https://www.geeksforgeeks.org/page/'
for page in range(1,10):
# pls note that the total number of
# pages in the website is more than 5000 so i'm only taking the
# first 10 as this is just an example
req = requests.get(URL + str(page) + '/')
soup = bs(req.text, 'html.parser')
titles = soup.find_all('div',attrs={'class','head'})
for i in range(4,19):
if page>1:
print(f"{(i-3)+page*15}" + titles[i].text)
else:
print(f"{i-3}" + titles[i].text)
sleep(randint(2,10))
输出:
现在,使用上面的代码,我们可以通过用循环将这些行夹在中间来获得所有文章的标题。
Python
import requests
from bs4 import BeautifulSoup as bs
URL = 'https://www.geeksforgeeks.org/page/'
for page in range(1,10):
# pls note that the total number of
# pages in the website is more than 5000 so i'm only taking the
# first 10 as this is just an example
req = requests.get(URL + str(page) + '/')
soup = bs(req.text, 'html.parser')
titles = soup.find_all('div',attrs={'class','head'})
for i in range(4,19):
if page>1:
print(f"{(i-3)+page*15}" + titles[i].text)
else:
print(f"{i-3}" + titles[i].text)
输出:
注意:上面的代码将从网站上获取前 10 个页面,并抓取这些页面下所有 150 个文章的标题。
示例 2:循环遍历不同 URL 的列表。
上面的技巧绝对很棒,但是如果您需要抓取不同的页面,而您不知道它们的页码怎么办?您需要一一抓取这些不同的 URL,并为每个此类网页手动编写脚本。
相反,您可以只列出这些 URL 并循环遍历它们。通过简单地迭代列表中的项目,即 URL,我们将能够提取这些页面的标题,而无需为每个页面编写代码。这是您如何做到这一点的示例代码。
Python
import requests
from bs4 import BeautifulSoup as bs
URL = ['https://www.geeksforgeeks.org','https://www.geeksforgeeks.org/page/10/']
for url in range(0,2):
req = requests.get(URL[url])
soup = bs(req.text, 'html.parser')
titles = soup.find_all('div',attrs={'class','head'})
for i in range(4, 19):
if url+1 > 1:
print(f"{(i - 3) + url * 15}" + titles[i].text)
else:
print(f"{i - 3}" + titles[i].text)
输出:
如何避免您的 IP 地址被禁止?
在执行非常大的提取时,控制爬行率是要记住的最重要的事情。在很短的时间内用多个请求轰炸服务器很可能会导致您的 IP 地址被列入黑名单。为了避免这种情况,我们可以简单地在很短的随机突发时间内进行爬行。换句话说,我们在抓取周期之间添加了暂停或少量中断,这有助于我们看起来像真正的人类,因为与尝试访问网站的人类相比,网站可以轻松识别抓取工具,因为它拥有的速度。这有助于避免不必要的流量和网站服务器过载。双赢!
现在,我们如何控制爬行率?这很简单。通过分别使用Python模块'random' 和 'time' 中的两个函数randint()和sleep() 。
蟒蛇3
from random import randint
from time import sleep
print(randint(1,10))
1
对于循环的每次迭代, randint()函数将在给定的上限和下限之间选择一个随机整数,在这种情况下,分别为 10 和 1。将randint()函数与sleep()函数结合使用将有助于在程序的爬行速度中添加短暂和随机的中断。 sleep()函数基本上会在给定的秒数内停止程序的执行。在此,秒的数量将随机地通过使用randint()函数送入睡眠函数。使用下面给出的代码作为参考。
蟒蛇3
from time import *
from random import randint
for i in range(0,3):
# selects random integer in given range
x = randint(2,5)
print(x)
sleep(x)
print(f'I waited {x} seconds')
5
I waited 5 seconds
4
I waited 4 seconds
5
I waited 5 seconds
为了让你清楚地了解这个函数的实际作用,请参考下面给出的代码。
蟒蛇3
import requests
from bs4 import BeautifulSoup as bs
from random import randint
from time import sleep
URL = 'https://www.geeksforgeeks.org/page/'
for page in range(1,10):
# pls note that the total number of
# pages in the website is more than 5000 so i'm only taking the
# first 10 as this is just an example
req = requests.get(URL + str(page) + '/')
soup = bs(req.text, 'html.parser')
titles = soup.find_all('div',attrs={'class','head'})
for i in range(4,19):
if page>1:
print(f"{(i-3)+page*15}" + titles[i].text)
else:
print(f"{i-3}" + titles[i].text)
sleep(randint(2,10))
输出: