一. 内容简介
python爬取网站数据,作为后端数据
二. 软件环境
2.1vsCode
2.2Anaconda
version: conda 22.9.0
2.3代码
链接:
三.主要流程
3.1 通过urllib请求网站
里面用的所有的包
! pip install lxml
! pip install selenium
! pip install pyautogui
通过urllib请求网站,需要注意一个问题,需要js加载的他都会没有,
使用 urllib 或 requests 库通常无法获取完整的页面内容,因为这些库只会获取页面的初始 HTML,而不会执行 JavaScript。
import urllib.request
from lxml import etree
import json
from selenium.webdriver.common.by import By
from selenium import webdriver
import random
import time
import pyautogui
from datetime import datetime
def urllibRequest(url):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'
}
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('UTF-8')
return content
url = "https://cxcy.upln.cn/"
print(url)
content = urllibRequest(url)
print(content)
最原始的网页,什么也没有,部分网页是这样的,没办法通过urllib 或 requests来获取完整的结构。
3.2 通过selenium请求网站
这个是通过驱动调用浏览器去进行访问,Selenium 可以模拟真实浏览器的行为,包括执行 JavaScript 代码,从而获取完整的页面内容。代码只需要给定链接,谷歌浏览器的exe位置,和网页加载时间就可以了,不需要下载谷歌浏览器驱动。
import urllib.request
from lxml import etree
import json
from selenium.webdriver.common.by import By
from selenium import webdriver
import random
import time
import pyautogui
from datetime import datetime
def seleniumRequest(url,chrome_path,waitTime):
options = webdriver.ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-automation'])
options.add_experimental_option('useAutomationExtension', False)
# 谷歌浏览器exe位置
options.binary_location = chrome_path
# 是否要启动页面
options.add_argument("--headless") # 启用无头模式
# GPU加速有时候会出bug
options.add_argument("--disable-gpu") # 禁用GPU加速
options.add_argument("--disable-blink-features=AutomationControlled")
driver = webdriver.Chrome(options=options)
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument',
{'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'})
# 启动要填写的地址,这就启动浏览器
driver.get(url)
# 这是关闭浏览器
# 等待页面加载,可以根据实际情况调整等待时间
driver.implicitly_wait(waitTime)
# 获取完整页面结构
full_page_content = driver.page_source
# 关闭浏览器
driver.quit()
return full_page_content
# # 处理完整页面结构
# print(full_page_content)
url = "https://cxcy.upln.cn/"
print(url)
chrome_path = r"C:\Program Files\Google\Chrome\Application\chrome.exe"
waitTime = 8
# 获取网页结构
# 通过selenium调用浏览器访问
content = seleniumRequest(url,chrome_path,waitTime)
print(content)
可以看到拿到了完整的网页结构了
3.2 通过request请求api,并保存json数据
import requests
import json
def apiRequset(api_url):
headers={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
}
# 发起带有头部信息的 GET 请求
response = requests.get(api_url, headers=headers)
# 检查请求是否成功
if response.status_code == 200:
# 解析 JSON 数据
data = response.json()
return data
api_url = 'https://cxcy.upln.cn/provincial/match/competition/queryOngoing?_t=1699950536&year=2023&code=2&column=createTime&order=desc&field=id,&pageNo=1&pageSize=10'
data = apiRequset(api_url)
json_data = json.dumps(data, indent=4)
# 将JSON数据写入文件
with open("data.json", "w") as json_file:
json_file.write(json_data)
3.4 通过xpath获取网页结构里面的数据,并存入json
xpath语法可以自己查一下,网上有很多
import urllib.request
from lxml import etree
import json
from selenium.webdriver.common.by import By
from selenium import webdriver
import random
import time
import pyautogui
from datetime import datetime
url = "https://cxcy.upln.cn/"
print(url)
imgs = []
chrome_path = r"C:\Program Files\Google\Chrome\Application\chrome.exe"
waitTime = 8
# 获取网页结构
# 通过selenium调用浏览器访问
content = seleniumRequest(url,chrome_path,waitTime)
# 这是直接请求得到的html,
# slelenium会拼接字符串
# content = urllibRequest(url)
# 给html变成tree用于xpath解析用
tree = etree.HTML(content)
# 改进的XPath表达式,选择你感兴趣的div元素
# 解析对应数据
bannerimgs = tree.xpath("//div[@class='img-box']//img/@src")
print(bannerimgs)
current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
for index, url in enumerate(bannerimgs):
print(index,url)
img = {
# 'img_id':,
'img_url':url,
'prod_id':None,
'seq':index+1,
'status':1,
'create_time':current_time,
'update_time':current_time,
}
imgs.append(img)
json_data = json.dumps(imgs, indent=4)
# 将JSON数据写入文件
with open("data.json", "w") as json_file:
json_file.write(json_data)
print("JSON数据已保存到文件")
3.4 读取json,将数据存入对应的数据库中
先下载驱动
! pip install mysql-connector-python
import json
import mysql.connector
# 读取JSON文件
with open('data.json', 'r') as file:
data = json.load(file)
# 连接到MySQL数据库
conn = mysql.connector.connect(
host='localhost',
port=3306, # MySQL默认端口号
user='root',
password='1234qwer',
database='competitionassistant'
)
cursor = conn.cursor()
# 创建表(如果不存在的话),并清空表数据
# cursor.execute('''
# CREATE TABLE IF NOT EXISTS your_table (
# id INT AUTO_INCREMENT PRIMARY KEY,
# name VARCHAR(255),
# age INT,
# other_field VARCHAR(255)
# )
# ''')
# 先清空一下表
cursor.execute('TRUNCATE TABLE index_img')
# 将数据插入数据库
for item in data:
# print(item)
# cursor.execute('''
# INSERT INTO index_img (img_url, prod_id, seq, status, create_time, update_time)
# VALUES (%s, %s, %s, %s, %s, %s)
# ''', (item['img_url'], item['prod_id'], item['seq'], item['status'], item['create_time'], item['update_time']))
sql_statement = f"""
INSERT INTO index_img (img_url, prod_id, seq, status, create_time, update_time)
VALUES ('{item['img_url']}', 0, {item['seq']}, {item['status']}, '{item['create_time']}', '{item['update_time']}')
"""
print(sql_statement)
cursor.execute(sql_statement)
# print()
# 提交更改并关闭连接
conn.commit()
conn.close()
有一个问题需要注意,这种拼接的,大部分情况都还好,都可以用,但是拼接链接以及时间这种里面有一些其他字符的情况下,他拼接好的语句给数据库是没办法执行的,他也不会报错,这样的问题就比较难找,所以我就直接用字符串拼接接了,不太安全。
INSERT INTO index_img (img_url, prod_id, seq, status, create_time, update_time)
VALUES (/img/bg3.f0b8e5f1.jpg, 0, 1, 1, '023-11-15 13:03:49, 2023-11-15 13:03:49)
cursor.execute('''
INSERT INTO index_img (img_url, prod_id, seq, status, create_time, update_time)
VALUES (%s, %s, %s, %s, %s, %s)
''', (item['img_url'], item['prod_id'], item['seq'], item['status'], item['create_time'], item['update_time']))
爬到的数据
执行代码存入数据库中
启动后端服务器,请求接口查询服务器,可以查到数据。