USER
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import csv
from webdriver_manager.chrome import ChromeDriverManager
def scroll_page(driver, scroll_amount=700):
"""Cuộn trang xuống một khoảng nhất định."""
driver.execute_script(
f"window.scrollBy(0, {scroll_amount});"
) # Cuộn xuống scroll_amount pixel
time.sleep(1) # Đợi nội dung mới tải về
def collect_links(driver, existing_links):
"""Thu thập các liên kết duy nhất từ phần tử match-container."""
match_links = driver.find_elements(
By.XPATH, "//a[contains(@class, 'match-container')]"
)
for link in match_links:
existing_links.add(link.get_attribute("href")) # Thêm vào tập
def scroll_full_page(driver):
match_links_set = set()
previous_size = 0
retries = 5
while retries > 0:
scroll_page(driver)
collect_links(driver, match_links_set)
if len(match_links_set) == previous_size:
retries -= 1
if retries == 0:
print("Không còn dữ liệu mới, dừng cuộn.")
break
else:
retries = 5
previous_size = len(match_links_set)
return match_links_set
def scroll_inside_element(driver, element):
"""Cuộn trong một phần tử cho đến khi không còn dữ liệu mới."""
last_height = driver.execute_script("return arguments[0].scrollHeight", element)
new_height = last_height + 1 # bắt đầu khác nhau để vào vòng lặp
while new_height > last_height:
last_height = driver.execute_script("return arguments[0].scrollHeight", element)
driver.execute_script(
"arguments[0].scrollTop = arguments[0].scrollHeight", element
)
time.sleep(2)
new_height = driver.execute_script("return arguments[0].scrollHeight", element)
def extract_and_save_table_data(driver, csv_writer, league, time_str, home, away, link):
"""Trích xuất dữ liệu từ bảng và lưu vào CSV."""
try:
# Xác định phần khung chứa body của bảng
table_body_wrapper = WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.CLASS_NAME, "el-table__body-wrapper"))
)
# Xác định body của bảng
table = table_body_wrapper.find_element(By.CLASS_NAME, "el-table__body")
# Lấy tất cả hàng trong bảng
rows = table.find_elements(By.TAG_NAME, "tr")
for row in rows:
row_data = [league, time_str, home, away] # Thêm thông tin trận đấu
# Xác định các cells trong hàng với từng trường hợp
cells = row.find_elements(By.TAG_NAME, "td")
# Kiểm tra xem hàng có 5 cột không
if len(cells) == 5:
for i in range(1, 6):
cell = row.find_element(
By.XPATH, f".//td[contains(@class, 'el-table_1_column_{i}')]"
)
cell_text = cell.text.strip()
row_data.append(cell_text)
# Kiểm tra hàng có 4 cột không (trong đó cột đầu tiên có colspan="2")
elif len(cells) == 4:
# Tìm ô có colspan=2 cho cột đầu tiên
colspan_cell = row.find_element(By.XPATH, ".//td[@colspan='2']")
cell_text = colspan_cell.text.strip()
row_data.append(cell_text)
# Lấy 3 ô còn lại
for i in range(3, 6):
cell = row.find_element(
By.XPATH, f".//td[contains(@class, 'el-table_1_column_{i}')]"
)
cell_text = cell.text.strip()
row_data.append(cell_text)
row_data.append(link) # Thêm link vào cuối mỗi dòng dữ liệu
# Ghi dữ liệu của hàng vào CSV
csv_writer.writerow(row_data)
print(f"Dữ liệu hàng: {row_data}")
except Exception as e:
print(f"Có lỗi xảy ra khi trích xuất dữ liệu bảng: {e}")
# Thiết lập ChromeDriver
chrome_options = Options()
chrome_options.add_argument("--log-level=3") # Chỉ hiển thị lỗi quan trọng
chrome_options.add_argument("--silent") # Tắt thông báo không cần thiết
chrome_options.add_argument(
"user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36"
)
driver = webdriver.Chrome(
service=Service(ChromeDriverManager().install()), options=chrome_options
)
try:
# Truy cập trang web
driver.get("https://www.aiscore.com/vi/20241008") # Thay URL của trang
driver.implicitly_wait(10) # Thời gian chờ tối đa là 10 giây
# Đợi trang tải và nhấp vào tab "Đã kết thúc"
print("Đang chờ tab 'Đã kết thúc' xuất hiện...")
ended_tab = WebDriverWait(driver, 60).until(
EC.element_to_be_clickable(
(By.XPATH, "//span[contains(text(), 'Đã kết thúc')]")
)
)
ended_tab.click()
# Đợi nội dung tải
print("Đang chờ nội dung mới được tải...")
WebDriverWait(driver, 10).until(
EC.presence_of_element_located(
(By.XPATH, "//div[contains(@class, 'vue-recycle-scroller__item-wrapper')]")
)
)
# Gọi hàm để xử lý dữ liệu
match_links = scroll_full_page(driver)
# Mở file CSV
with open("match_data.csv", mode="w", newline="", encoding="utf-8") as csvfile:
csvwriter = csv.writer(csvfile)
csvwriter.writerow(["Time", "Score", "Bàn Thắng", "Tài", "Xỉu"])
for link in match_links:
driver.get(link)
WebDriverWait(driver, 40).until(
lambda d: d.execute_script("return document.readyState") == "complete"
)
# Chỉ xử lý liên kết đầu tiên
# if match_links:
# link = next(iter(match_links)) # Lấy phần tử đầu tiên từ tập hợp
# driver.get(link)
# WebDriverWait(driver, 40).until(
# lambda d: d.execute_script("return document.readyState") == "complete"
# )
try:
tile_cuoc_tab = WebDriverWait(driver, 10).until(
EC.presence_of_element_located(
(
By.XPATH,
"//a[contains(text(), 'Tỷ lệ cược') and contains(@class, 'tab')]",
)
)
)
tile_cuoc_tab.click()
print("Đã nhấn vào tab 'Tỷ lệ cược'.")
time.sleep(5) # Thêm thời gian chờ để dữ liệu tải
try:
next_element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable(
(
By.XPATH,
"//*[@id='app']/div[3]/div[4]/span/div/div[1]/div[2]/div[2]/div[3]/i",
)
)
)
next_element.click()
print("Đã nhấn vào phần tử tiếp theo.")
try:
sobt_tab = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable(
(
By.XPATH,
"//span[contains(text(), 'Số bàn thắng Tài/Xỉu') and contains(@class, 'changeItem')]",
)
)
)
sobt_tab.click()
print("Đã nhấn vào 'Số bàn thắng Tài/Xỉu'.")
extract_and_save_table_data(driver, csvwriter)
except Exception:
print(
"Phần tử 'Số bàn thắng Tài/Xỉu' không tồn tại hoặc không thể nhấp."
)
except Exception:
print("Phần tử tiếp theo không tồn tại.")
except Exception:
print("Tab 'Tỷ lệ cược' không tồn tại.")
except Exception as e:
print(f"Đã xảy ra lỗi: {e}")
finally:
# Đóng trình duyệt
driver.quit()
đây mới là code gốc của tôi, hãy chỉnh sửa lại dùm nhéASSISTANT
Dưới đây là cách bạn có thể điều chỉnh mã để phù hợp với yêu cầu của bạn, đảm bảo thứ tự truy cập và trích xuất thông tin như bạn đã mô tả. Đầu tiên, chúng ta sẽ truy cập vào liên kết chi tiết của từng trận đấu, sau đó trích xuất thông tin giải đấu, thời gian, đội nhà, đội khách trước khi nhấp vào các tab cụ thể để lấy thêm dữ liệu:
```python
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import csv
from webdriver_manager.chrome import ChromeDriverManager
def scroll_page(driver, scroll_amount=700):
"""Cuộn trang xuống một khoảng nhất định."""
driver.execute_script(
f"window.scrollBy(0, {scroll_amount});"
)
time.sleep(1)
def collect_links(driver, existing_links):
"""Thu thập các liên kết duy nhất từ phần tử match-container."""
match_links = driver.find_elements(
By.XPATH, "//a[contains(@class, 'match-container')]"
)
for link in match_links:
existing_links.add(link.get_attribute("href"))
def scroll_full_page(driver):
match_links_set = set()
previous_size = 0
retries = 5
while retries > 0:
scroll_page(driver)
collect_links(driver, match_links_set)
if len(match_links_set) == previous_size:
retries -= 1
if retries == 0:
print("Không còn dữ liệu mới, dừng cuộn.")
break
else:
retries = 5
previous_size = len(match_links_set)
return match_links_set
def extract_and_save_table_data(driver, csv_writer, league, time_str, home, away, link):
"""Trích xuất dữ liệu từ bảng và lưu vào CSV."""
try:
table_body_wrapper = WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.CLASS_NAME, "el-table__body-wrapper"))
)
table = table_body_wrapper.find_element(By.CLASS_NAME, "el-table__body")
rows = table.find_elements(By.TAG_NAME, "tr")
for row in rows:
row_data = [league, time_str, home, away]
cells = row.find_elements(By.TAG_NAME, "td")
if len(cells) == 5:
for i in range(1, 6):
cell = row.find_element(
By.XPATH, f".//td[contains(@class, 'el-table_1_column_{i}')]"
)
cell_text = cell.text.strip()
row_data.append(cell_text)
elif len(cells) == 4:
colspan_cell = row.find_element(By.XPATH, ".//td[@colspan='2']")
cell_text = colspan_cell.text.strip()
row_data.append(cell_text)
for i in range(3, 6):
cell = row.find_element(
By.XPATH, f".//td[contains(@class, 'el-table_1_column_{i}')]"
)
cell_text = cell.text.strip()
row_data.append(cell_text)
row_data.append(link)
csv_writer.writerow(row_data)
print(f"Dữ liệu hàng: {row_data}")
except Exception as e:
print(f"Có lỗi xảy ra khi trích xuất dữ liệu bảng: {e}")
def extract_match_info(driver):
"""Trích xuất thông tin giải đấu, thời gian, đội nhà, đội khách."""
try:
league = driver.find_element(By.CSS_SELECTOR, "CSS_SELECTOR_FOR_LEAGUE").text
time_str = driver.find_element(By.CSS_SELECTOR, "CSS_SELECTOR_FOR_TIME").text
home = driver.find_element(By.CSS_SELECTOR, "CSS_SELECTOR_FOR_HOME_TEAM").text
away = driver.find_element(By.CSS_SELECTOR, "CSS_SELECTOR_FOR_AWAY_TEAM").text
return league, time_str, home, away
except Exception as e:
print(f"Lỗi khi trích xuất thông tin trận đấu: {e}")
return "", "", "", ""
chrome_options = Options()
chrome_options.add_argument("--log-level=3")
chrome_options.add_argument("--silent")
chrome_options.add_argument(
"user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36"
)
driver = webdriver.Chrome(
service=Service(ChromeDriverManager().install()), options=chrome_options
)
try:
driver.get("https://www.aiscore.com/vi/20241008")
driver.implicitly_wait(10)
print("Đang chờ tab 'Đã kết thúc' xuất hiện...")
ended_tab = WebDriverWait(driver, 60).until(
EC.element_to_be_clickable(
(By.XPATH, "//span[contains(text(), 'Đã kết thúc')]")
)
)
ended_tab.click()
print("Đang chờ nội dung mới được tải...")
WebDriverWait(driver, 10).until(
EC.presence_of_element_located(
(By.XPATH, "//div[contains(@class, 'vue-recycle-scroller__item-wrapper')]")
)
)
match_links = scroll_full_page(driver)
with open("match_data.csv", mode="w", newline="", encoding="utf-8") as csvfile:
csvwriter = csv.writer(csvfile)
csvwriter.writerow(["League", "Time", "Home", "Away", "Score", "Over-Under", "Over", "Under", "Asian Handicap", "Link"])
for link in match_links:
driver.get(link)
WebDriverWait(driver, 40).until(
lambda d: d.execute_script("return document.readyState") == "complete"
)
league, time_str, home, away = extract_match_info(driver)
try:
tile_cuoc_tab = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable(
(
By.XPATH,
"//a[contains(text(), 'Tỷ lệ cược') and contains(@class, 'tab')]",
)
)
)
tile_cuoc_tab.click()
print("Đã nhấn vào tab 'Tỷ lệ cược'.")
time.sleep(5)
try:
next_element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable(
(
By.XPATH,
"//*[@id='app']/div[3]/div[4]/span/div/div[1]/div[2]/div[2]/div[3]/i",
)
)
)
next_element.click()
print("Đã nhấn vào phần tử tiếp theo.")
try:
sobt_tab = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable(
(
By.XPATH,
"//span[contains(text(), 'Số bàn thắng Tài/Xỉu') and contains(@class, 'changeItem')]",
)
)
)
sobt_tab.click()
print("Đã nhấn vào 'Số bàn thắng Tài/Xỉu'.")
extract_and_save_table_data(driver, csvwriter, league, time_str, home, away, link)
except Exception:
print("Phần tử 'Số bàn thắng Tài/Xỉu' không tồn tại hoặc không thể nhấp.")
except Exception:
print("Phần tử tiếp theo không tồn tại.")
except Exception:
print("Tab 'Tỷ lệ cược' không tồn tại.")
except Exception as e:
print(f"Đã xảy ra lỗi: {e}")
finally:
driver.quit()
```
### Thay đổi cần thiết:
1. **CSS Selector cho các thông tin trận đấu**: Thay thế `CSS_SELECTOR_FOR_LEAGUE`, `CSS_SELECTOR_FOR_TIME`, `CSS_SELECTOR_FOR_HOME_TEAM`, `CSS_SELECTOR_FOR_AWAY_TEAM` bằng CSS selector thực tế của bạn. Bạn cần mở trang web và kiểm tra cấu trúc HTML để viết CSS selector phù hợp.
2. **Thông tin trong `csv_writer.writerow`**: Đảm bảo cột CSV được khớp đúng với tiêu đề bạn mong muốn ở phần đầu tệp CSV.
3. **Xử lý ngoại lệ và logs**: Kiểm tra, xử lý lỗi và log thông tin chi tiết khi không thể lấy dữ liệu để dễ dàng chẩn đoán vấn đề.
Hãy đảm bảo rằng các xpath và CSS selectors được cập nhật phù hợp với các thành phần cụ thể trên trang web của bạn.