Python爬虫,破解ajax动态网页,爬取篮球比赛数据
蚂蚁学Python
共 2932字,需浏览 6分钟
·
2021-12-30 09:01
前言
今天遇到了群友的一个需求:
爬取 https://www.sporttery.cn/jc/lqsgkj/ 全年的篮球赛果开奖数据,如下所示
一、网站分析
这个网站的数据不是静态的,是动态加载的(选取相应日期,点击”开始查询“后,数据从服务端加载到浏览器)
看一下网页的低端,发现数据并不是一次性加载的,而是通过分页的形式完成 进一步研究还发现,每个月份的分页数并不是一致的,最多有8页
对日期的输入框进行分析,发现它是可以直接通过键盘输入日期的
二:确定爬取方案
对于这种动态的网页,直接通过request库不太好爬取,而模拟人类操作浏览器的selenium对这种场景具有天然优势,所以我采用后者。对网页元素的定位则使用xpath。再此推荐蚂蚁老师的爬虫课程,简洁清晰,新手入门必备。
大概的思路就是,先构建每月的开始月份、结束月份
date = [("2021-01-01", "2021-01-31"), ("2021-02-01", "2021-02-28"), ("2021-03-01", "2021-03-31"),
("2021-04-01", "2021-04-30"), ("2021-05-01", "2021-05-31"), ("2021-06-01", "2021-06-30"),
("2021-07-01", "2021-07-31"),
("2021-08-01", "2021-08-30"), ("2021-09-01", "2021-09-31"), ("2021-10-01", "2021-10-30"),
("2021-11-01", "2021-11-31"),
("2021-12-01", "2021-12-24")]
再用这些数据分别输入到开始框和结束框内
点击查询
点击分页 特别注意到分页的xpath路径是有规律的,因而我们可以构造xpath路径,方便接下来的爬取
Xpath = [f'//*[@id="matchList"]/div/div/ul/li[{i}]' for i in range(2, 10)]
爬取内容
三:编码实现
from selenium.webdriver import Edge
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
import time
driver = Edge(executable_path="C:/WebDriver/bin/msedgedriver.exe")
date = [("2021-01-01", "2021-01-31"), ("2021-02-01", "2021-02-28"), ("2021-03-01", "2021-03-31"),
("2021-04-01", "2021-04-30"), ("2021-05-01", "2021-05-31"), ("2021-06-01", "2021-06-30"),
("2021-07-01", "2021-07-31"),
("2021-08-01", "2021-08-30"), ("2021-09-01", "2021-09-31"), ("2021-10-01", "2021-10-30"),
("2021-11-01", "2021-11-31"),
("2021-12-01", "2021-12-24")]
Xpath = [f'//*[@id="matchList"]/div/div/ul/li[{i}]' for i in range(2, 10)]
# 判断xpath存不存在的函数
def NodeExists(xpath):
try:
driver.find_element_by_xpath(xpath)
return True
except:
return False
def crawler():
for item in date:
# 打开网页
driver.get("https://www.sporttery.cn/jc/lqsgkj/")
# 等待加载
WebDriverWait(driver, 10).until(lambda d: "篮球赛果开奖" in d.title)
# 等待一秒后 先清空再输入开始日期
time.sleep(1)
driver.find_element(By.XPATH, '//*[@id="start_date"]').clear()
driver.find_element(By.XPATH, '//*[@id="start_date"]').send_keys(item[0])
# 再等一秒 先清空再输入结束日期
time.sleep(1)
driver.find_element(By.XPATH, '//*[@id="end_date"]').clear()
driver.find_element(By.XPATH, '//*[@id="end_date"]').send_keys(item[1])
# 点击查询
driver.find_element(By.XPATH, '//*[@id="headerTr"]/div[1]/div[1]/div/a').click()
print(f"开始爬取{item[0]}")
with open(f"{item[0]}.csv", "w", encoding='ANSI') as fin:
# 点击1-8页内容
page = 1
for this in Xpath:
time.sleep(1)
if NodeExists(this):
driver.find_element(By.XPATH, this).click()
else:
print(f"没有{this}这个xpath")
break
time.sleep(1)
content = driver.find_element(By.XPATH, '//*[@id="matchList"]/table').text
fin.write("\n" + content)
print(f"完成第{page}页的爬取,此时的xpath是:{this}")
page += 1
print(f"结束爬取{item[0]}")
if __name__ == "__main__":
crawler()
最后,推荐蚂蚁老师的《零基础学Python到数据分析实战》包含了爬虫部分:
评论