首页 > 解决方案 > Python Webscraping:我如何循环许多 url 请求?

问题描述

import requests
from bs4 import BeautifulSoup
LURL="https://www.erkunde-die-welt.de/laender-hauptstaedte-welt/"
Lpage = requests.get(LURL)
Lsoup = BeautifulSoup(Lpage.content, 'html.parser')
Lx = Lsoup.find_all(class_="column-2")
a=[]
for Lx in Lx:
  a.append(Lx.text)
a.remove("Land")
j=0
for i in range(len(a)):
  b = a[j]
  URL = "https://de.wikipedia.org/wiki/"+b
  page = requests.get(URL)
  soup = BeautifulSoup(page.content, 'html.parser')
  l = soup.find(class_="firstHeading")
  zr = soup.find(class_="wikitable infobox infoboxstaat float-right")
  z = zr.findAll("tr")
  a=""
  for z in z:
    a=a+z.text
  h=a.find("Hauptstadt")
  lol=a[h:-1]
  lol=lol.replace("Hauptstadt", "")
  lol=lol.strip()
  fg=lol.find("\n")
  lol=lol[0:fg]
  lol=lol.strip()
  j=j+1
  print(lol)
  print(l.text)

这是代码。它获取每个国家/地区的名称并将其打包成一个列表。之后,程序循环浏览各个国家的维基百科页面,获取该国的首都并打印出来。它适用于每个国家/地区。但是在一个国家/地区完成并再次启动代码后,它会停止工作并出现错误:

Traceback (most recent call last):   File "main.py", line 19, in <module>
    z = zr.findAll("tr") AttributeError: 'NoneType' object has no attribute 'findAll'

标签: pythonbeautifulsoup

解决方案


错误消息实际上是在告诉您发生了什么。代码行

z = zr.findAll("tr")

正在引发属性错误,因为 NoneType 对象没有findAll属性。您正在尝试调用findAllzr,假设该变量将始终是 BeautifulSoup 对象,但它不会。如果这一行:

zr = soup.find(class_="wikitable infobox infoboxstaat float-right")

在 html 中找不到与这些类匹配的对象,zr 将设置为None. 因此,在您尝试抓取的页面之一上,这就是发生的事情。您可以使用 try/except 语句围绕它进行编码,如下所示:

for i in range(len(a)):
    b = a[j]
    URL = "https://de.wikipedia.org/wiki/"+b
    page = requests.get(URL)
    try:
        soup = BeautifulSoup(page.content, 'html.parser')
        l = soup.find(class_="firstHeading")
        zr = soup.find(class_="wikitable infobox infoboxstaat float-right")
        z = zr.findAll("tr")
        a=""
        #don't do this! should be 'for i in z' or something other variable name
        for z in z:
            a=a+z.text
            h=a.find("Hauptstadt")
            lol=a[h:-1]
            lol=lol.replace("Hauptstadt", "")
            lol=lol.strip()
            fg=lol.find("\n")
            lol=lol[0:fg]
            lol=lol.strip()
            j=j+1
            print(lol)
            print(l.text)
    except:
        pass

在此示例中,将跳过任何没有正确 html 标记的页面。


推荐阅读