不确定如何通过网络抓取可能位于多个不同位置的特定值

Unsure how to web-scrape a specific value that could be in several different places

所以我一直在研究一个网络抓取程序,但在最后一点上遇到了一些困难。

有个网站是这样显示游戏内战斗记录的:

示例 1:https://zkillboard.com/kill/44998359/

示例 2:https://zkillboard.com/kill/44917133/

我一直在尝试抓取击杀球员的全部信息。这意味着他们的名字、他们的公司名称和他们的联盟名称。

以上例子的信息是:

示例 1:名称 = Happosait, Corp. = Arctic Light Inc., Alliance = Arctic Light

示例 2:名称 = Lord Veninal,Corp. = Sniggerdly,联盟 = Pandemic Legion

虽然 "Final Blow" 始终与名称一起列在右上角,但该名称也没有公司和联盟。完整信息始终列在下方右侧栏“## Involved”中,但他们在该栏中的位置取决于他们在战斗中造成的伤害,因此它并不总是在顶部或特定于此的任何地方重要的。

所以虽然我可以得到他们的名字:

kbPilotName = soup.find_all('td', style="text-align: center;")[0].find_all('a', href=re.compile('/character/'))[0].img.get('alt')

我怎样才能得到他们的其余信息?

有一个 textarea 元素包含您要查找的所有数据。这一切都在一个文本中,但它是结构化的。您可以选择不同的方式来解析它,但这里是一个使用正则表达式的示例:

import re

from bs4 import BeautifulSoup
import requests

url = 'https://zkillboard.com/kill/44998359/'

pattern = re.compile(r"(?s)Name: (.*?)Security: (.*?)Corp: (.*?)Alliance: (.*?)")

with requests.Session() as session:
    session.headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36'}

    response = session.get(url)    
    soup = BeautifulSoup(response.content)

    data = soup.select('form.form textarea#eft')[0].text

    for name, security, corp, alliance in pattern.findall(data):
        print name.strip()

打印:

Happosait (laid the final blow)
Baneken
Perkel
Tibor Vherok
Kheo Dons
Kayakka
Lina Ectelion
Jay Burner
Zalamus
Draacan Ferox
Luwanii
Jousen Momaki
Varcuntis Morannear
Grimm K-Man
Wob'Niar
Godfrey Silvarna
Quintus Corvus
Shadow Altair
Sieren
Isha Vir
Argyrosdraco
Jack None
Strixi

替代解决方案(解析 "involved" 页面):

from bs4 import BeautifulSoup
import requests

url = 'https://zkillboard.com/kill/44998359/'
involved_url = 'https://zkillboard.com/kill/44998359/involved/'

with requests.Session() as session:
    session.headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36'}

    session.get(url)

    response = session.get(involved_url)
    soup = BeautifulSoup(response.content)

    for row in soup.select('table.table tr.attacker'):
        name, corp, alliance = row.select('td.pilot > a')
        print name.text, corp.text, alliance.text