Python 爬虫爬取京东商品信息

news2024/9/16 10:00:40

Python 爬虫爬取京东商品信息 下面我将逐一解释每一部分的代码

导入库

from selenium import webdriver
from selenium.webdriver.edge.service import Service
from selenium.webdriver.edge.options import Options
import time
import random
import csv
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from pyquery import PyQuery as pq
import os
import requests
from datetime import datetime
import re
  • 作用:导入所有必要的库和模块。

  • 技术栈
    • selenium: 用于自动化浏览器操作。

    • time, random: 用于添加延迟和生成随机数。

    • csv: 用于读写CSV文件。

    • os: 用于文件系统操作。

    • requests: 用于发送HTTP请求(例如下载图片)。

    • datetime: 用于处理日期和时间。

    • re: 用于正则表达式匹配。

配置变量

KEYWORD = '美妆'
CSV_FILE = 'DepartmentStore.csv'
id = 3538
dratenums = 5
drate = 5
num = 5
  • 作用:初始化全局变量。

  • 技术栈:无特殊技术栈。

设置WebDriver

# 创建EdgeOptions对象
options = Options()

# 设置Edge WebDriver的路径
webdriver_path = 'G:\\大三下暑期实训基于电商商品推荐平台\\爬虫\\a\\msedgedriver.exe'
service = Service(webdriver_path)

# 初始化Edge WebDriver
driver = webdriver.Edge(service=service, options=options)

# 窗口最大化
driver.maximize_window()

wait = WebDriverWait(driver, 15)
  • 作用:初始化Microsoft Edge WebDriver。

  • 技术栈
    • selenium: 用于自动化浏览器操作。

函数定义

search_goods 函数
def search_goods(start_page, total_pages):
    # ...
  • 作用:搜索特定商品并处理翻页逻辑。

  • 技术栈
    • selenium: 用于自动化浏览器操作。

    • pyquery: 用于解析HTML文档。

    • time: 用于添加延迟。

    • random: 用于生成随机数。

page_turning 函数
def page_turning(page_number):
    # ...
  • 作用:实现翻页操作。

  • 技术栈selenium: 用于自动化浏览器操作。

random_sleep 函数
def random_sleep(timeS, timeE):
    # ...
  • 作用:随机等待一段时间,防止被网站检测到爬虫行为。

  • 技术栈time, random: 用于添加延迟和生成随机数。

scroll_smoothly 函数
def scroll_smoothly(duration):
    # ...
  • 作用:平滑滚动页面以模拟真实用户行为。

  • 技术栈selenium: 用于自动化浏览器操作。

get_goods 函数
def get_goods():
    # ...
  • 作用:获取商品列表中的具体信息。

  • 技术栈
    • selenium: 用于自动化浏览器操作。

    • pyquery: 用于解析HTML文档。

    • os: 用于文件系统操作。

    • requests: 用于发送HTTP请求(例如下载图片)。

    • datetime: 用于处理日期和时间。

    • re: 用于正则表达式匹配。

save_to_csv 函数
def save_to_csv(result):
    # ...
  • 作用:将获取到的商品信息保存到CSV文件中。

  • 技术栈csv: 用于读写CSV文件。

main 函数
def main():
    # ...
  • 作用:主函数,用于启动爬虫并处理异常。

  • 技术栈:无特殊技术栈。

主程序入口

if __name__ == '__main__':
    main()
  • 作用:程序的入口点。

  • 技术栈:无特殊技术栈。

接下来,我将针对每个函数进行详细的代码解释。

search_goods 函数

def search_goods(start_page, total_pages):
    print('正在搜索: ')
    try:
        driver.get('https://www.taobao.com')
        time.sleep(10)
        driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",
                               {"source": """Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"""})
        input = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#q")))
        submit = wait.until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, '#J_TSearchForm > div.search-button > button')))
        input.send_keys(KEYWORD)
        submit.click()
        time.sleep(10)

        if start_page != 1:
            driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
            random_sleep(1, 3)
            pageInput = wait.until(EC.presence_of_element_located(
                (By.XPATH, '//*[@id="root"]/div/div[3]/div[1]/div[1]/div[2]/div[4]/div/div/span[3]/input')))
            pageInput.send_keys(start_page)
            admit = wait.until(EC.element_to_be_clickable(
                (By.XPATH, '//*[@id="root"]/div/div[3]/div[1]/div[1]/div[2]/div[4]/div/div/button[3]')))
            admit.click()

        get_goods()

        for i in range(start_page + 1, start_page + total_pages):
            page_turning(i)
    except TimeoutException:
        print("search_goods: error")
        return search_goods(start_page, total_pages)
  • 作用:搜索特定商品并处理翻页逻辑。

  • 细节
    • 打开淘宝网站并等待页面加载。

    • 使用CDP命令禁用WebDriver标志,以防被网站检测。

    • 在搜索框中输入关键词并提交。

    • 如果不是第一页,则跳转到指定的起始页。

    • 调用get_goods函数获取商品信息。

    • 循环翻页并获取商品信息。

page_turning 函数

def page_turning(page_number):
    print('正在翻页: ', page_number)
    try:
        submit = wait.until(
            EC.element_to_be_clickable((By.XPATH, '//*[@id="sortBarWrap"]/div[1]/div[2]/div[2]/div[8]/div/button[2]')))
        submit.click()
        wait.until(EC.text_to_be_present_in_element(
            (By.XPATH, '//*[@id="sortBarWrap"]/div[1]/div[2]/div[2]/div[8]/div/span/em'), str(page_number)))
        get_goods()
    except TimeoutException:
        page_turning(page_number)
  • 作用:实现翻页操作。

  • 细节
    • 点击下一页按钮。

    • 等待新的页面加载完成。

    • 调用get_goods函数获取商品信息。

random_sleep 函数

def random_sleep(timeS, timeE):
    random_sleep_time = random.uniform(timeS, timeE)
    time.sleep(random_sleep_time)
  • 作用:随机等待一段时间,防止被网站检测到爬虫行为。

  • 细节
    • 生成一个在timeStimeE之间的随机数作为睡眠时间。

    • 使用time.sleep暂停指定的时间。

scroll_smoothly 函数

def scroll_smoothly(duration):
    total_height = driver.execute_script("return document.body.scrollHeight")
    viewport_height = driver.execute_script("return window.innerHeight")
    steps = 30  # 分成30步
    step_duration = duration / steps  # 每步的时间
    step_height = (total_height - viewport_height) / steps  # 每步的高度

    for i in range(steps):
        driver.execute_script(f"window.scrollBy(0, {step_height});")
        time.sleep(step_duration)
  • 作用:平滑滚动页面以模拟真实用户行为。

  • 细节
    • 计算页面的总高度和视窗的高度。

    • 计算每次滚动的距离和时间。

    • 使用JavaScript执行平滑滚动效果。

get_goods 函数

def get_goods():
    global id, drate, dratenums, num  # 声明使用全局变量 id
    random_sleep(2, 4)
    # 滑动浏览器滚轮,向下滑动
    scroll_smoothly(4)
    random_sleep(4, 4)  # 等待页面加载
    html = driver.page_source
    doc = pq(html)
    items = doc(
        'div.PageContent--contentWrap--mep7AEm > div.LeftLay--leftWrap--xBQipVc > div.LeftLay--leftContent--AMmPNfB > div.Content--content--sgSCZ12 > div > div').items()

    for item in items:
        title = item.find('.Title--title--jCOPvpf span').text()
        price_int = item.find('.Price--priceInt--ZlsSi_M').text()
        price_float = item.find('.Price--priceFloat--h2RR0RK').text()
        if price_int and price_float:
            price = float(f"{price_int}{price_float}")
        else:
            price = 0.0
        deal = item.find('.Price--realSales--FhTZc7U').text()
        location = item.find('.Price--procity--_7Vt3mX').text()
        shop = item.find('.ShopInfo--TextAndPic--yH0AZfx a').text()
        postText = item.find('.SalesPoint--subIconWrapper--s6vanNY span').text()
        result = 1 if "包邮" in postText else 0
        image = item.find('.MainPic--mainPicWrapper--iv9Yv90 img').attr('src')
        # 图片的URL
        image_url = image
        pattern = r"https:\/\/.*?\.jpg"

        match = re.search(pattern, image_url)
        if match:
            print("Extracted URL:", match.group(0))
        else:
            print("No match found")
        image_url = match.group(0)

        # 保存图片的文件夹
        save_folder = "shopping_cover"

        # 确保保存路径存在
        if not os.path.exists(save_folder):
            os.makedirs(save_folder)

        # 将图片文件名固定为 '1.jpg'
        image_name = str(id) + ".jpg"

        # 完整的保存路径
        save_path = os.path.join(save_folder, image_name)

        # 获取当前日期
        current_date = datetime.now()

        # 格式化日期为 'yyyy-mm-dd'
        formatted_date = current_date.strftime('%Y-%m-%d')

        imdblink = item.find('.Card--doubleCardWrapper--L2XFE73 a').attr('href')

        # 下载图片并保存
        try:
            with requests.get(image_url, stream=True) as response:
                response.raise_for_status()
                with open(save_path, 'wb') as f:
                    for chunk in response.iter_content(chunk_size=8192):
                        if chunk:  # filter out keep-alive new chunks
                            f.write(chunk)
            print(f"图片已保存到: {save_path}")
            product = {
                'id': id,
                'name': title,
                'director': shop,
                'country': location,
                'years': formatted_date,
                'leader': price,
                'd_rate_nums': dratenums,
                'd_rate': drate,
                'intro': deal + str(result),
                'num': num,
                'orign_image_link': image,
                'image_link': save_folder + '/' + image_name,
                'imdb_link': imdblink
            }
            save_to_csv(product)
            id += 1
        except requests.RequestException as e:
            print(f"下载图片失败:{e}")

        # 直接滑动浏览器滚轮到最顶部
        driver.execute_script("window.scrollTo(0, 0);")
  • 作用:获取商品列表中的具体信息。

  • 细节
    • 使用pyquery解析HTML源码。

    • 提取每个商品的信息。

    • 下载并保存商品图片。

    • 调用save_to_csv保存数据。

save_to_csv 函数

def save_to_csv(result):
    try:
        with open(CSV_FILE, mode='a', newline='', encoding='utf-8') as file:
            writer = csv.writer(file)
            writer.writerow([result['id'], result['name'], result['director'], result['country'], result['years'], result['leader'], result['d_rate_nums'], result['d_rate'], result['intro'], result['num'], result['orign_image_link'], result['image_link'], result['imdb_link']])
        print('存储到CSV成功: ', result)
    except Exception as e:
        print('存储到CSV出错: ', result, e)
  • 作用:将获取到的商品信息保存到CSV文件中。

  • 细节
    • 将商品信息追加到CSV文件中。

    • 输出保存成功的消息或错误消息。

main 函数

def main():
    try:
        # 检查文件是否存在,如果不存在则创建并写入标题行
        if not os.path.exists(CSV_FILE):
            with open(CSV_FILE, mode='w', newline='', encoding='utf-8') as file:
                writer = csv.writer(file)
                writer.writerow(['id', 'name', 'director', 'country', 'years', 'leader', 'd_rate_nums', 'd_rate', 'intro', 'num', 'orign_image_link', 'image_link', 'imdb_link'])

        pageStart = int(input("输入您想开始爬取的页面数: "))
        pageAll = int(input("输入您想爬取的总页面数: "))
        search_goods(pageStart, pageAll)
    except Exception as e:
        print('main函数报错: ', e)
  • 作用:主函数,用于启动爬虫并处理异常。

  • 细节
    • 检查CSV文件是否存在,若不存在则创建并写入表头。

    • 获取用户输入的起始页和总页数。

    • 调用search_goods函数开始爬取。

主程序入口

if __name__ == '__main__':
    main()
  • 作用:程序的入口点。

  • 细节:当直接运行此文件时,执行main函数。

以下是完整代码
from selenium import webdriver
from selenium.webdriver.edge.service import Service
from selenium.webdriver.edge.options import Options
import time
import random
import csv
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from pyquery import PyQuery as pq
import os
import requests
from datetime import datetime
import re

KEYWORD = '美妆'
CSV_FILE = 'DepartmentStore.csv'
id = 3538
dratenums = 5
drate = 5
num = 5

# 创建EdgeOptions对象
options = Options()

# 设置Edge WebDriver的路径
webdriver_path = 'G:\\大三下暑期实训基于电商商品推荐平台\\爬虫\\a\\msedgedriver.exe'
service = Service(webdriver_path)

# 初始化Edge WebDriver
driver = webdriver.Edge(service=service, options=options)

# 窗口最大化
driver.maximize_window()

wait = WebDriverWait(driver, 15)

def search_goods(start_page, total_pages):
    print('正在搜索: ')
    try:
        driver.get('https://www.taobao.com')
        time.sleep(10)
        driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",
                               {"source": """Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"""})
        input = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#q")))
        submit = wait.until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, '#J_TSearchForm > div.search-button > button')))
        input.send_keys(KEYWORD)
        submit.click()
        time.sleep(10)

        if start_page != 1:
            driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
            random_sleep(1, 3)
            pageInput = wait.until(EC.presence_of_element_located(
                (By.XPATH, '//*[@id="root"]/div/div[3]/div[1]/div[1]/div[2]/div[4]/div/div/span[3]/input')))
            pageInput.send_keys(start_page)
            admit = wait.until(EC.element_to_be_clickable(
                (By.XPATH, '//*[@id="root"]/div/div[3]/div[1]/div[1]/div[2]/div[4]/div/div/button[3]')))
            admit.click()

        get_goods()

        for i in range(start_page + 1, start_page + total_pages):
            page_turning(i)
    except TimeoutException:
        print("search_goods: error")
        return search_goods(start_page, total_pages)

def page_turning(page_number):
    print('正在翻页: ', page_number)
    try:
        submit = wait.until(
            EC.element_to_be_clickable((By.XPATH, '//*[@id="sortBarWrap"]/div[1]/div[2]/div[2]/div[8]/div/button[2]')))
        submit.click()
        wait.until(EC.text_to_be_present_in_element(
            (By.XPATH, '//*[@id="sortBarWrap"]/div[1]/div[2]/div[2]/div[8]/div/span/em'), str(page_number)))
        get_goods()
    except TimeoutException:
        page_turning(page_number)

def random_sleep(timeS, timeE):
    random_sleep_time = random.uniform(timeS, timeE)
    time.sleep(random_sleep_time)

def scroll_smoothly(duration):
    total_height = driver.execute_script("return document.body.scrollHeight")
    viewport_height = driver.execute_script("return window.innerHeight")
    steps = 30  # 分成30步
    step_duration = duration / steps  # 每步的时间
    step_height = (total_height - viewport_height) / steps  # 每步的高度

    for i in range(steps):
        driver.execute_script(f"window.scrollBy(0, {step_height});")
        time.sleep(step_duration)

def get_goods():
    global id, drate, dratenums, num  # 声明使用全局变量 id
    random_sleep(2, 4)
    # 滑动浏览器滚轮,向下滑动
    scroll_smoothly(4)
    random_sleep(4, 4)  # 等待页面加载
    html = driver.page_source
    doc = pq(html)
    items = doc(
        'div.PageContent--contentWrap--mep7AEm > div.LeftLay--leftWrap--xBQipVc > div.LeftLay--leftContent--AMmPNfB > div.Content--content--sgSCZ12 > div > div').items()

    for item in items:
        title = item.find('.Title--title--jCOPvpf span').text()
        price_int = item.find('.Price--priceInt--ZlsSi_M').text()
        price_float = item.find('.Price--priceFloat--h2RR0RK').text()
        if price_int and price_float:
            price = float(f"{price_int}{price_float}")
        else:
            price = 0.0
        deal = item.find('.Price--realSales--FhTZc7U').text()
        location = item.find('.Price--procity--_7Vt3mX').text()
        shop = item.find('.ShopInfo--TextAndPic--yH0AZfx a').text()
        postText = item.find('.SalesPoint--subIconWrapper--s6vanNY span').text()
        result = 1 if "包邮" in postText else 0
        image = item.find('.MainPic--mainPicWrapper--iv9Yv90 img').attr('src')
        # 图片的URL
        image_url = image
        pattern = r"https:\/\/.*?\.jpg"

        match = re.search(pattern, image_url)
        if match:
            print("Extracted URL:", match.group(0))
        else:
            print("No match found")
        image_url = match.group(0)

        # 保存图片的文件夹
        save_folder = "shopping_cover"

        # 确保保存路径存在
        if not os.path.exists(save_folder):
            os.makedirs(save_folder)

        # 将图片文件名固定为 '1.jpg'
        image_name = str(id) + ".jpg"

        # 完整的保存路径
        save_path = os.path.join(save_folder, image_name)

        # 获取当前日期
        current_date = datetime.now()

        # 格式化日期为 'yyyy-mm-dd'
        formatted_date = current_date.strftime('%Y-%m-%d')

        imdblink = item.find('.Card--doubleCardWrapper--L2XFE73 a').attr('href')

        # 下载图片并保存
        try:
            with requests.get(image_url, stream=True) as response:
                response.raise_for_status()
                with open(save_path, 'wb') as f:
                    for chunk in response.iter_content(chunk_size=8192):
                        if chunk:  # filter out keep-alive new chunks
                            f.write(chunk)
            print(f"图片已保存到: {save_path}")
            product = {
                'id': id,
                'name': title,
                'director': shop,
                'country': location,
                'years': formatted_date,
                'leader': price,
                'd_rate_nums': dratenums,
                'd_rate': drate,
                'intro': deal + str(result),
                'num': num,
                'orign_image_link': image,
                'image_link': save_folder + '/' + image_name,
                'imdb_link': imdblink
            }
            save_to_csv(product)
            id += 1
        except requests.RequestException as e:
            print(f"下载图片失败:{e}")

        # 直接滑动浏览器滚轮到最顶部
        driver.execute_script("window.scrollTo(0, 0);")

def save_to_csv(result):
    try:
        with open(CSV_FILE, mode='a', newline='', encoding='utf-8') as file:
            writer = csv.writer(file)
            writer.writerow([result['id'], result['name'], result['director'], result['country'], result['years'], result['leader'], result['d_rate_nums'], result['d_rate'], result['intro'], result['num'], result['orign_image_link'], result['image_link'], result['imdb_link']])
        print('存储到CSV成功: ', result)
    except Exception as e:
        print('存储到CSV出错: ', result, e)

def main():
    try:
        # 检查文件是否存在,如果不存在则创建并写入标题行
        if not os.path.exists(CSV_FILE):
            with open(CSV_FILE, mode='w', newline='', encoding='utf-8') as file:
                writer = csv.writer(file)
                writer.writerow(['id', 'name', 'director', 'country', 'years', 'leader', 'd_rate_nums', 'd_rate', 'intro', 'num', 'orign_image_link', 'image_link', 'imdb_link'])

        pageStart = int(input("输入您想开始爬取的页面数: "))
        pageAll = int(input("输入您想爬取的总页面数: "))
        search_goods(pageStart, pageAll)
    except Exception as e:
        print('main函数报错: ', e)

if __name__ == '__main__':
    main()

 最后,如果觉得本项目对你有帮助的话,求求点个star🤩吧,谢谢了~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2117016.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

推荐清晖一套不错的讲解沟通的线上讲座

推荐清晖一套不错的讲解沟通的线上讲座,比较实际贴地,听完了推荐给大家: 《项目管理中的沟通策略,听出弦外之音,变身沟通达人》 地址:项目管理中的沟通策略,听出弦外之音,变身沟通达…

数据结构(1):ArrayList和顺序表

数据结构(Data Structure)是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合。 下面我们就开一个新坑,数据结构。数据结构,简单来说就是存放数据的方式,这些方式多种多样,我们来一点一…

Statcounter Global Stats 提供全球统计数据信息

Statcounter Global Stats 提供全球统计数据信息 1. Statcounter Global Stats2. Mobile & Tablet Android Version Market Share WorldwideReferences Statcounter Global Stats https://gs.statcounter.com/ Statcounter Global Stats are brought to you by Statcounte…

C++ 定时器

这是第一次独立设计一个模块,从接口定义,模块组合到多线程并发可能遇到的各种问题,虽然定时挺简单的,但是想设计精度高,并且能应对高并发似乎也不是很容易,当然,最后没有测试定时器的代码&#…

架构模式:MVC

引言 MVC,即 Model(模型)-View(视图)-Controller(控制器),是广泛应用于交互式系统中的典型架构模式,尤其在 GUI 和 Web 应用中。 MVC 的概念源自 GOF(Gang …

JS解密工具之**如何续期 Charles 的 SSL 证书**

本文由 jsjiami加密/一键JS解密 独家赞助 有问题请私聊加密官方客服 Charles 是一款常用的 HTTP 代理工具,用于调试网络请求。然而,Charles 的 SSL 证书会定期过期,如果 SSL 证书失效,你将无法对 HTTPS 请求进行抓包。本文将详细…

SQL语句中in条件超过1000怎么办?

博客主页: 南来_北往 系列专栏:Spring Boot实战 引言 当遇到SQL语句中IN条件超过1000个的情况时,可以采取以下几种策略来有效处理这一问题: 使用临时表:将IN列表中的值存储在临时表中,并将该临时表与查询表进行J…

【Python 千题 —— 算法篇】寻找最长回文子串

Python 千题持续更新中 …… 脑图地址 👉:⭐https://twilight-fanyi.gitee.io/mind-map/Python千题.html⭐ 题目背景 回文串是指一个字符串从左到右和从右到左读都是一样的。寻找一个字符串中的最长回文子串是许多经典算法问题之一,广泛应…

2024年9月最新界面:自己如何在电脑上注册新的Google谷歌账号,图文详解和关键点解析、常见问题

有一些朋友需要通过谷歌账号来工作、学习或娱乐(例如很多游戏需要用谷歌账号来注册和使用),但是不知道如何注册谷歌账号,或者知道如何注册,但是对于一些步骤或者注意事项不太熟悉,导致注册不成功&#xff0…

什么是LED智能会议一体机?COB超微小间距LED会议一体机大势所趋

LED智能会议一体机,作为现代会议室革新的核心装备,正逐步颠覆传统会议模式的界限。它不仅仅是一台集成了高清显示、触控互动、音视频处理及远程协作等功能于一体的智能设备,更是推动会议效率与体验双重飞跃的关键力量。随着技术的不断进步&am…

【重学 MySQL】十八、逻辑运算符的使用

【重学 MySQL】十八、逻辑运算符的使用 AND运算符OR运算符NOT运算符异或运算符使用 XOR 关键字使用 BIT_XOR() 函数注意事项 注意事项 在MySQL中,逻辑运算符是构建复杂查询语句的重要工具,它们用于处理布尔类型的数据,进行逻辑判断和组合条件…

【Protobuf】初识protobuf以及详细安装教程

W...Y的主页 😊 代码仓库分享 💕 目录 序列化概念 ProtoBuf是什么 ProtoBuf在window下的安装 下载ProtoBuf编译器 配置环境变量 ​编辑 检查是否配置成功 ​编辑 ProtoBuf在Linux下的安装 下载ProtoBuf 安装ProtoBuf 序列化概念 首先我们…

小白开发中遇到的问题和解决方案

小白开发中遇到的问题和解决方案 文章目录 小白开发中遇到的问题和解决方案问题一 问题一 问题:端口别占用可能开开启多个应用 解决方法–在cmd执行下方红框中的命令关闭所有应用

MyBatis-MappedStatement什么时候生成?QueryWrapper如何做到动态生成了SQL?

通过XML配置的MappedStatement 这部分MappedStatement主要是由MybatisXMLMapperBuilder进行解析,核心逻辑如下: 通过注解配置的MappedStatement 核心逻辑就在这个里面了: 继承BaseMapper的MappedStatement 我们看看这个类,里…

idea如何配置模板

配置生成代码指令模板 注:我们常用的有sout,main等指令 第一步打开设置面板 1)按如下操作 2)或者CtrlAltS快捷键直接弹出 第二步找 Editor>LiveTemplates 如下图 第三步创建模板 步骤如下 1)创建分组名字 2)分组名字 3)创…

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p

pycharm如何安装selenium

在pycharm中打开一个项目后,点击Setting(ALTCtrlS快捷键) 然后点击install package完成后点击关闭这个窗口,就可以在代码中使用selenium了 成功后出现如下界面 编写一段正常可以运行操作chorme浏览器的 from selenium import webdriver # 指定ChromeDriver的路径driver we…

关于 PC打开“我的电脑”后有一些快捷如腾讯视频、百度网盘、夸克网盘、迅雷等各种捷方式在磁盘驱动器上面统一删除 的解决方法

若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/142029325 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV…

淘宝开放平台交易类API解析以及如何测试?

调用淘宝开放平台的订单接口,主要可以通过以下几种途径进行: 1. 直接使用淘宝开放平台提供的API接口 步骤概述: 注册淘宝开放平台账号:首先,你需要在淘宝开放平台注册一个开发者账号。创建应用:在注册并…

Unity3D 小案例 像素贪吃蛇 01 蛇的移动

Unity3D 小案例 像素贪吃蛇 第一期 蛇的移动 像素贪吃蛇 今天来简单制作一个小案例,经典的像素贪吃蛇。 准备 首先调整一下相机的设置,这里使用灰色的纯色背景,正交视图。 接着,创建一个正方形,保存为预制体&#…