簡體   English   中英

使用 Python 和 bs4 從圖像中抓取“標題”

[英]Scraping 'Title' from image with Python and bs4

我是用 Python 抓取的新手,需要一些幫助。 我在一家 BI 顧問公司實習期間正在做我自己的第一個項目,並且正在構建一個數據模型以在 Qlik Sense 中使用。

我已經設法從以下位置抓取名稱和值: Transfermarkt但現在我想抓取俱樂部和國家的名稱(用圖片可視化)。 圖像抓取是另一回事(據我所知,需要一組完全不同的代碼)。 但我想要標題,例如“法國”。 有人可以指出我正確的方向嗎?

代碼更新為 Pablos 響應。 現在我得到錯誤:

Traceback (most recent call last):
  File "c:/Users/cljkn/Desktop/Python scraper github/.vscode/Scraping Transfermarkt.py", line 33, in <module>
    df = pd.DataFrame({"Players":PlayersList,"Values":ValuesList,"Nationality":NationalityList})
  File "C:\Users\cljkn\Desktop\Python scraper github\.venv\lib\site-packages\pandas\core\frame.py", line 435, in __init__
    mgr = init_dict(data, index, columns, dtype=dtype)
  File "C:\Users\cljkn\Desktop\Python scraper github\.venv\lib\site-packages\pandas\core\internals\construction.py", line 254, in init_dict
    return arrays_to_mgr(arrays, data_names, index, columns, dtype=dtype)
  File "C:\Users\cljkn\Desktop\Python scraper github\.venv\lib\site-packages\pandas\core\internals\construction.py", line 64, in arrays_to_mgr
    index = extract_index(arrays)
  File "C:\Users\cljkn\Desktop\Python scraper github\.venv\lib\site-packages\pandas\core\internals\construction.py", line 365, in extract_index
    raise ValueError("arrays must all be same length")
ValueError: arrays must all be same length
import requests
from bs4 import BeautifulSoup

import pandas as pd

headers = {'User-Agent':
            'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36'}

page = "https://www.transfermarkt.com/spieler-statistik/wertvollstespieler/marktwertetop"
pageTree = requests.get(page, headers=headers)
pageSoup = BeautifulSoup(pageTree.content, 'html.parser')

Players = pageSoup.find_all("a", {"class": "spielprofil_tooltip"})

Values = pageSoup.find_all("td", {"class": "rechts hauptlink"})

Nationality = pageSoup.find_all("td", {"class": "flaggenrahmen"}, {"title"})
for nat in Nationality:
    img = nat.find('img')
    title = img.get('title')

PlayersList = []
ValuesList = []
NationalityList = []

for i in range(0,25):
    PlayersList.append(Players[i].text)
    ValuesList.append(Values[i].text)
    NationalityList.append(Nationality[i].text)

NationalityList.append('title')

df = pd.DataFrame({"Players":PlayersList,"Values":ValuesList,"Nationality":NationalityList})

df.head()

df.to_csv (r'C:\Users\cljkn\Desktop\Python scraper github\export_dataframe.csv', index = False, header=True)

print(df)

任何有關編碼或源材料的直接幫助將不勝感激。

那么在這種情況下,我們需要使用regex 因為HTML混雜了一些屬性。

例如 :

title="https://www.transfermarkt.us/spieler-statistik/wertvollstespieler/marktwertetop"/>

title="France"

所以我們需要使用re來匹配不以http開頭的title

import re

for item in soup.findAll("img", class_="flaggenrahmen", title=re.compile("^(?!http).*")):
    print(item.get("title"))

輸出將是:

France
England
Jamaica
Brazil
Senegal
Egypt
England
Belgium
Argentina
Spain
England
France
England
Portugal
France
Mali
Germany
France
Netherlands
Suriname
France
Slovenia
Belgium
Portugal
Netherlands
Germany
Argentina
Italy
Germany
Cote d'Ivoire
Spain
Brazil

現在我們將討論另一個問題:你有two clubs而不是one two clubs players

如:

現在讓我們解決這個問題。 這是完整的代碼:

import requests
from bs4 import BeautifulSoup
import re
import csv

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0'
}
r = requests.get(
    "https://www.transfermarkt.com/spieler-statistik/wertvollstespieler/marktwertetop", headers=headers)

soup = BeautifulSoup(r.text, 'html.parser')

names = []
values = []
nats = []


for name in soup.findAll("img", class_="bilderrahmen-fixed"):
    names.append(name.get("alt"))

for value in soup.findAll("td", class_="rechts hauptlink"):
    values.append(value.get_text(strip=True))

for td in soup.findAll("td", class_="zentriert"):
    inner_grp = []
    for item in td.findAll("img", class_="flaggenrahmen", title=re.compile("^(?!http).*")):
        #print(item.get('title'), end='')
        if item.get('title'):
            inner_grp.append(item.get('title'))
    if inner_grp:
        nats.append(inner_grp)

with open("result.csv", 'w', newline="") as f:
    writer = csv.writer(f)
    writer.writerow(["Name", "Value", "Nat"])
    for a, b, c in zip(names, values, nats):
        writer.writerow([a, b, ", ".join(c)])

print("Done")

輸出: 在線檢查

在此處輸入圖片說明

使用 find_all,您將獲得帶有“flaggenrahmen”類的“td”列表。 如果你想要標題,你需要遍歷“國籍”對象和 .get('title')。

編輯的解決方案:

Nationality = pageSoup.find_all("td", {"class": "flaggenrahmen"}, {"title"})
for nat in Nationality:
    img = nat.find('img')
    title = img.get('title')

PlayersList = []
ValuesList = []
NationalityList = []

for i in range(0,25):
    PlayersList.append(Players[i].text)
    ValuesList.append(Values[i].text)
    NationalityList.append(nationality_list[i].text)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM