Scraper cho đội bóng rổ

Sep 24 2020

Tôi còn rất mới với Python và tôi đang cố gắng học qua các dự án cá nhân và hôm nay tôi cần thu thập rất nhiều tên người chơi baksetball và quyết định đây là thời điểm tốt để học và luyện tập.

Tập lệnh có thể lấy ra tất cả tên người chơi, chiều cao, quốc tịch và DOB nhưng tôi cần nhập liên kết đến các trang trước khi khởi chạy nó. Bước tiếp theo sẽ là xây dựng một giao diện đồ họa nơi tôi có thể sao chép / dán các liên kết hoặc yêu cầu trong trình ướt bảng điều khiển mà tôi muốn gia nhập một nhóm mới.

Tôi rất mong nhận được phản hồi từ bạn vì đây có thể là dự án cá nhân đầu tiên của tôi :)

import os
import requests
import pandas as pd
import xlsxwriter
from bs4 import BeautifulSoup

def reverse(name):
    to_reverse = name
    return ' '.join(reversed(name.split(' ')))

def conversion_df(url):
    requete = requests.get(url)
    page = requete.content
    soup = BeautifulSoup(page, features="lxml")

    header = [th.getText() for th in soup.findAll("th")]    # Why do I have to put th. before getText for it to work | Why do we use th as an updator 
    header = header[1:5] # Here we exclude the first (O) entry and we display the entries situated before 5

    row = soup.findAll("tr")[1:]
    stats = [[td.getText().strip() for td in row[i]] for i in range(len(row))]
    for j in stats: 
        del j[0]
        del j[4]
    #print(stats)

    for i in range(len(stats)):
        stats[i][0] = reverse(stats[i][0])

    table = pd.DataFrame(data = stats, columns = header)
    return table

nanterre = conversion_df("https://www.lnb.fr/fr/espa/equipe/espoirs-nanterre-61344.html")
monaco = conversion_df("https://www.lnb.fr/fr/espa/equipe/espoirs-monaco-61343.html")
boulazac = conversion_df("https://www.lnb.fr/fr/espoirs/equipe/espoirs-boulazac-61331.html")
boulogne = conversion_df("https://www.lnb.fr/fr/espoirs/equipe/espoirs-boulogne-levallois-61332.html")
bourg = conversion_df("https://www.lnb.fr/fr/espoirs/equipe/espoirs-bourg-en-bresse-61333.html")
chalon = conversion_df("https://www.lnb.fr/fr/espoirs/equipe/espoirs-chalon-saone-61334.html")
cholet = conversion_df("https://www.lnb.fr/fr/espoirs/equipe/espoirs-cholet-61336.html")
chalon_reims = conversion_df("https://www.lnb.fr/fr/espoirs/equipe/espoirs-chalons-reims-61335.html")
dijon = conversion_df("https://www.lnb.fr/fr/espoirs/equipe/espoirs-dijon-61337.html")
gravelines = conversion_df("https://www.lnb.fr/fr/espoirs/equipe/espoirs-gravelines-dunkerque-61338.html")
le_mans = conversion_df("https://www.lnb.fr/fr/espoirs/equipe/espoirs-le-mans-61339.html")
le_portel = conversion_df("https://www.lnb.fr/fr/espoirs/equipe/espoirs-le-portel-61340.html")
orleans = conversion_df("https://www.lnb.fr/fr/espoirs/equipe/espoirs-orleans-61345.html")
pau = conversion_df("https://www.lnb.fr/fr/espoirs/equipe/espoirs-pau-lacq-orthez-61346.html")
roanne = conversion_df("https://www.lnb.fr/fr/espoirs/equipe/espoirs-roanne-61347.html")
strasbourg = conversion_df("https://www.lnb.fr/fr/espoirs/equipe/espoirs-strasbourg-61348.html")
limoges = conversion_df("https://www.lnb.fr/fr/espoirs/equipe/espoirs-limoges-61341.html")
lyon = conversion_df("https://www.lnb.fr/fr/espoirs/equipe/espoirs-lyon-villeurbanne-61342.html")

clubs = [boulazac,boulogne,bourg,chalon,cholet,chalon_reims,dijon,gravelines,le_mans,le_portel,limoges,lyon,monaco,nanterre,orleans,pau,roanne,strasbourg]

# Creating Excel Writer Object from Pandas  
writer = pd.ExcelWriter('liste_espoir.xlsx',engine='xlsxwriter')   
workbook=writer.book
worksheet=workbook.add_worksheet('Espoirs')
writer.sheets['Espoirs'] = worksheet

row_count = 0
i = 0

for i in range(len(clubs)):
    clubs[i].to_excel(writer,sheet_name='Espoirs',startrow=row_count , startcol=0)   
    row_count += 20

writer.save()

Trả lời

4 hjpotter92 Sep 25 2020 at 05:00

Chào mừng bạn đến với Đánh giá mã. Mã của bạn có vẻ đang tuân theo một số phương pháp hay từ hướng dẫn kiểu của python (PEP-8). Tuy nhiên, là một lập trình viên, bạn có thể cải thiện cấu trúc / hiệu suất.

  1. Không cần phải có các biến riêng biệt cho khung dữ liệu cho từng câu lạc bộ. Nhóm tất cả các liên kết lại với nhau và sử dụng a mapđể tìm nạp mọi thứ.
  2. Hàm đảo ngược xác định một biến không sử dụng to_reverse.
  3. Tách chức năng thành chức năng riêng biệt, giống như bạn có một chức năng để đảo ngược tên.
  4. Bạn không cần phải lặp lại range(len(some_iterable))nếu chỉ mục không cần thiết.
  5. Thêm gợi ý về loại và một số nhận xét vào các hàm để giúp hiểu loại giá trị mà nó có thể mong đợi (và trả về), cũng như những gì nó đang làm.
  6. Đặt mọi thứ bên trong một if __name__ == "__main__"mệnh đề.

Mã viết lại:

from typing import Tuple
import requests
import pandas as pd
import xlsxwriter
from bs4 import BeautifulSoup


def reverse(name: str) -> str:
    """Reverse name from 'Last First' to 'First Last'."""
    return " ".join(reversed(name.split(" ")))


def fetch_page(url: str) -> str:
    """Send request to given url, and return the contents on success."""
    response = requests.get(url)
    if response.ok:
        return response.content


def get_club_information(club_page) -> Tuple:
    """Read all `tr` elements on page, and extract player information.

    Each row (`tr`) consists of 6 cells. We are skipping over 1st and last cell data."""
    soup = BeautifulSoup(club_page, features="lxml")
    rows = soup.findAll("tr")
    header, *content = [[cell.getText().strip() for cell in row][1:5] for row in rows]
    for row in content:
        row[0] = reverse(row[0])
    return header, content


def conversion_df(url):
    page = fetch_page(url)
    header, content = get_club_information(page)
    print(header, content)
    table = pd.DataFrame(data=content, columns=header)
    return table


LINKS = (
    "https://www.lnb.fr/fr/espa/equipe/espoirs-nanterre-61344.html",
    "https://www.lnb.fr/fr/espa/equipe/espoirs-monaco-61343.html",
    "https://www.lnb.fr/fr/espoirs/equipe/espoirs-boulazac-61331.html",
    "https://www.lnb.fr/fr/espoirs/equipe/espoirs-boulogne-levallois-61332.html",
    "https://www.lnb.fr/fr/espoirs/equipe/espoirs-bourg-en-bresse-61333.html",
    "https://www.lnb.fr/fr/espoirs/equipe/espoirs-chalon-saone-61334.html",
    "https://www.lnb.fr/fr/espoirs/equipe/espoirs-cholet-61336.html",
    "https://www.lnb.fr/fr/espoirs/equipe/espoirs-chalons-reims-61335.html",
    "https://www.lnb.fr/fr/espoirs/equipe/espoirs-dijon-61337.html",
    "https://www.lnb.fr/fr/espoirs/equipe/espoirs-gravelines-dunkerque-61338.html",
    "https://www.lnb.fr/fr/espoirs/equipe/espoirs-le-mans-61339.html",
    "https://www.lnb.fr/fr/espoirs/equipe/espoirs-le-portel-61340.html",
    "https://www.lnb.fr/fr/espoirs/equipe/espoirs-orleans-61345.html",
    "https://www.lnb.fr/fr/espoirs/equipe/espoirs-pau-lacq-orthez-61346.html",
    "https://www.lnb.fr/fr/espoirs/equipe/espoirs-roanne-61347.html",
    "https://www.lnb.fr/fr/espoirs/equipe/espoirs-strasbourg-61348.html",
    "https://www.lnb.fr/fr/espoirs/equipe/espoirs-limoges-61341.html",
    "https://www.lnb.fr/fr/espoirs/equipe/espoirs-lyon-villeurbanne-61342.html",
)


def main():
    # Creating Excel Writer Object from Pandas
    writer = pd.ExcelWriter("liste_espoir.xlsx", engine="xlsxwriter")
    workbook = writer.book
    writer.sheets["Espoirs"] = workbook.add_worksheet("Espoirs")
    row_count = 0
    for club in map(conversion_df, LINKS):
        club.to_excel(writer, sheet_name="Espoirs", startrow=row_count, startcol=0)
        row_count += 20
    writer.save()


if __name__ == "__main__":
    main()

Ngoài ra, bạn có thể sử dụng asyncio để tìm nạp các trang đó song song, nhằm giảm thời gian chạy cho chương trình của bạn.