मैं स्क्रैपिंग में नया हूं, और मुझे अपने अधिकांश कोड के साथ मदद मिली है, मैं अब फैंसी या "सही तरीके से लिखने" के लिए नहीं जा रहा हूं, बस इसे काम करने की कोशिश कर रहा हूं। यह मेरी इंटर्नशिप में एक प्रोजेक्ट के लिए है।

मैं Transfermarkt पर 500 सबसे मूल्यवान खिलाड़ियों के बारे में जानकारी प्राप्त करने का प्रयास कर रहा हूं। मैंने नाम, मूल्य, राष्ट्रीयता, क्लब, स्थिति, खिलाड़ी की छवि और क्लब की छवि को परिमार्जन करने में कामयाबी हासिल की है। मैं भी देश की छवि को परिमार्जन करना चाहता हूं। मैं परिणामों को एक सीएसवी में सहेजना चाहता हूं, जिसे मैंने पूरा किया है। लेकिन देश की छवि के साथ नहीं। अन्य सभी स्तंभों में ५०० पंक्तियाँ हैं, लेकिन देश की छवियों की सूची में १००७ हैं। यह मेरा त्रुटि संदेश है:

`Traceback (most recent call last):
  File "c:/Users/cljkn/Desktop/Python scraper github/.vscode/Scraping Transfermarkt.py", line 60, in <module>
    df = pd.DataFrame({"Player":names,"Club":clubs, "Nationality":nats,"Position":position,"Value":values, "PlayerImgURL":playerURL,"ClubImgURL":clubURL,"CountryImgURL":natURL})
  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`

मैंने कई अलग-अलग चीजों के साथ कोशिश की है और कोशिश की है। समस्या क्या हो सकती है, यह देखने के लिए मैंने सूची को कई बार छापा है, और ऐसा लगता है कि कुछ खिलाड़ियों की राष्ट्रीयता में दो झंडे हैं, मेरा अनुमान है कि उनके पास दोहरे नागरिक जहाज हैं। ऐसा होने पर स्रोत कोड में एक विराम होता है, और मैंने केवल पहला मान पढ़ने का प्रयास किया है, लेकिन मैं इसे काम पर नहीं ला सकता। मैंने समाधान के लिए ऑनलाइन खोज की है लेकिन मुझे अपनी आवश्यकताओं के अनुरूप कुछ भी नहीं मिल रहा है। मैंने एक समाधान की कोशिश की है जहां मैं प्रत्येक खिलाड़ी प्रोफाइल दर्ज करता हूं और फिर वहां से छवि प्राप्त करता हूं, लेकिन मुझे वह काम नहीं मिल रहा है। मुझे ऑनलाइन कुछ भी नहीं मिला है जो इसमें मेरी मदद करता है। मैंने उन्हें हटाकर अपनी सूची में डुप्लीकेट की जांच की है, इससे मुझे भी मदद नहीं मिलती है।

यहाँ मेरा अब तक का कोड है, और जैसा कि मैंने कहा, अधिकांश मेरे द्वारा नहीं किया गया है। समस्या #CountryImgURL में है:

import requests
from bs4 import BeautifulSoup
import csv
import pandas as pd
import re

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0'
}

pages = range(1, 21)

names = []
values = []
nats = []
clubs = []
position = []
playerURL = []
clubURL=[]
natURL=[]


for page in pages:

    r = requests.get(
        "https://www.transfermarkt.co.uk/spieler-statistik/wertvollstespieler/marktwertetop?page=%d" % page, headers=headers)

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

    for table in soup.find_all('table', attrs={'class': 'inline-table'}):
        content = table.contents
        names.append(content[0].text)  # Name
        position.append(content[1].text)  # Position

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

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

    for club in soup.findAll("img", src=re.compile("^http"), class_="", title=True)[:25]: #Club
        clubs.append(club.get("alt"))

    for img in soup.find_all('img', class_='bilderrahmen-fixed'): #PlayerImageURL
        playerURL.append(img.get('src'))

    for img in soup.find_all("img", class_="flaggenrahmen"): #CountryImageURL
        natURL.append(img.get('src'))

    for img in soup.findAll("img", src=re.compile("^http"), class_="", title=True)[:25]: #ClubImgURL
        clubURL.append(img.get('src'))


df = pd.DataFrame({"Player":names,"Club":clubs, "Nationality":nats,"Position":position,"Value":values, "PlayerImgURL":playerURL,"ClubImgURL":clubURL,"CountryImgURL":natURL})

df.head()

df.to_csv (r'S:\_ALL\Internal Projects\Introduction_2020\Transfermarkt\PlayerDetails.csv', index = False, header=True)

print(df)
1
Zakan 20 मार्च 2020, 22:31

1 उत्तर

सबसे बढ़िया उत्तर

जैसा कि आपने देखा है कि राष्ट्रीयता के लिए 1 से अधिक देश हो सकते हैं। आप यहां natUrl सूची में कई बार जोड़ रहे हैं:

for img in soup.find_all("img", class_="flaggenrahmen"): #CountryImageURL
    natURL.append(img.get('src'))

इसलिए जब आप अंत में डेटाफ़्रेम का निर्माण करते हैं, तो सूचियों का आकार समान नहीं होता है जिसके परिणामस्वरूप असंगतता होती है जैसे खिलाड़ी [x] की राष्ट्रीयता [x + 1] होगी क्योंकि खिलाड़ी [x-1] में 2 राष्ट्रीयताएँ थीं। वास्तव में, यदि आप चाहते हैं कि सभी सरणी का आकार एक जैसा हो और आपके कोड में बहुत सारे लूप हैं, तो संभवतः आपको प्रति पुनरावृत्ति में एक आइटम जोड़ना होगा (यदि कई img टैग हैं)

मैंने केवल समझ सूची का उपयोग करके एक उदाहरण बनाया है:

from bs4 import BeautifulSoup
import requests
import pandas as pd

result = []

for page in range(1, 21):

    r = requests.get("https://www.transfermarkt.co.uk/spieler-statistik/wertvollstespieler/marktwertetop",
        params= {"page": page},
        headers= {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0"}
    )
    soup = BeautifulSoup(r.content, "html.parser")

    tr = soup.find_all("tbody")[1].find_all("tr", recursive=False)

    result.extend([
        { 
            "Player": t[1].find_all("td")[1].text,
            "Club": t[4].find("img")["alt"],
            "Nationality": t[3].find("img")["alt"], # for all nationality : [ i["alt"] for i in t[3].find_all("img")], 
            "Position": t[1].find_all("td")[2].text,
            "Value": t[5].text.strip(),
            "PlayerImgURL": t[1].find_all("img")[0]["src"],
            "ClubImgURL": t[4].find("img")["src"],
            "CountryImgURL": t[3].find("img")["src"] # for all country url: [ i["src"] for i in t[3].find_all("img")]
        }
        for t in (t.find_all(recursive=False) for t in tr)
    ])

df = pd.DataFrame(result)

df.to_csv('test.csv', index = False, header=True)
0
Bertrand Martel 20 मार्च 2020, 22:44