分享

Python反爬虫(2) | Python爬虫,破解ajax动态网页,爬取篮球比赛数据

 O听_海_轩O 2022-01-24


前言

今天遇到了群友的一个需求:

爬取 https://www.sporttery.cn/jc/lqsgkj/ 全年的篮球赛果开奖数据,如下所示图片

一、网站分析

这个网站的数据不是静态的,是动态加载的(选取相应日期,点击”开始查询“后,数据从服务端加载到浏览器)

图片
img

看一下网页的低端,发现数据并不是一次性加载的,而是通过分页的形式完成 图片 进一步研究还发现,每个月份的分页数并不是一致的,最多有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(210)]

爬取内容图片

三:编码实现

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(210)]


# 判断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()

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多