当前位置: 首页 > wzjs >正文

wordpress响应式加后台seo课程培训班

wordpress响应式加后台,seo课程培训班,中企动力做的网站,wordpress 内容替换目录 系列文章 1. 引言 2 技术栈Request 2.1请求头headers 2.2查找定位信息 2.3处理网页html结构化数据 2.4每页url规律 2.5逐条查找所需信息 2.6完整代码 3 数据存储至mysql 3.1新建数据库 3.2编写数据库写入py文件 3.2.1构建1个执行sql语句的函数 3.2.2构造一个…

目录

系列文章

1. 引言

2 技术栈Request

2.1请求头headers

2.2查找定位信息

2.3处理网页html结构化数据

2.4每页url规律

2.5逐条查找所需信息

2.6完整代码

3 数据存储至mysql

3.1新建数据库

3.2编写数据库写入py文件

3.2.1构建1个执行sql语句的函数

3.2.2构造一个将dataframe转成sql语句的函数

3.2.3完整代码

4 总结


系列文章

虫洞数观系列总览 | 技术全景:豆瓣电影TOP250数据采集→分析→可视化完整指南

1. 引言

豆瓣电影TOP250以其清晰的页面结构、规律的数据排列(如电影名称、评分、导演等信息的固定标签和类名),成为爬虫练习的理想目标。虽然存在请求频率限制、IP检测等反爬机制,但相比淘宝、微博等大型网站,其反爬措施较为宽松。本文将基于Requests和Selenium两种技术栈,演示如何高效爬取该榜单数据。

网址链接豆瓣电影 Top 250

2 技术栈Request

2.1请求头headers

headers 是 HTTP 请求中的一部分,用于向服务器传递客户端(如浏览器)的相关信息。服务器会根据这些信息来判断请求的来源、客户端类型以及如何处理请求。主要作用是绕过反爬虫机制,通过模拟浏览器行为,避免被服务器识别为爬虫。

在网站中如何查找自己的请求头


Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36

请求头解读:

  • Mozilla/5.0:这是一个通用的标识符,表示客户端兼容 Mozilla 浏览器(现代浏览器通常都会包含这个字段)。

  • Windows NT 10.0; Win64; x64:表示客户端的操作系统信息。

    • Windows NT 10.0:操作系统是 Windows 10。

    • Win64 和 x64:表示系统是 64 位架构。

  • AppleWebKit/537.36:表示客户端使用的渲染引擎是 AppleWebKit(Chrome 和 Safari 都基于此引擎)。

  • KHTML, like Gecko:表示客户端兼容 KHTML 和 Gecko 渲染引擎(Gecko 是 Firefox 的渲染引擎)。

  • Chrome/134.0.0.0:表示客户端使用的是 Chrome 浏览器,版本号为 134.0.0.0。

  • Safari/537.36:表示客户端兼容 Safari 浏览器,版本号为 537.36。

2.2查找定位信息

很多人可能一开始不理解xpath,尤其看到网页信息,如"/html/body/div[3]/div[1]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a/span[1]"就感觉头大,不重要!!!,重在理解大致含义,看久啦就习惯啦,慢慢就理解啦,以下是告诉你怎么查看xpath

2.3处理网页html结构化数据

在使用 requests 请求网页后,返回的数据通常是 HTML 格式的结构化文本。HTML 文档由标签、属性和内容组成,具有清晰的层次结构。以下是一个简单的 HTML 示例,展示了其典型的结构:

<div class="info"><div class="hd"><a href="https://movie.douban.com/subject/1292052/"><span class="title">肖申克的救赎</span></a></div>
</div>

在处理网页数据时,虽然可以直接对 requests.text(即原始的 HTML 字符串)进行操作,但这种方式会面临极大的工作量。HTML 文档通常包含复杂的标签嵌套和属性结构,手动解析字符串不仅繁琐,还容易出错。为了高效、准确地提取目标数据,引入 etree,将 HTML 字符串解析为树形结构(ElementTree)。这种结构化解析方式不仅简化了数据提取过程,还支持强大的 XPath 和 CSS 选择器,极大地提升了开发效率。

以下是一个简单的示例,展示如何使用 etree 解析 HTML 并提取数据:

from lxml import etreetree = etree.HTML(html)
# 使用 XPath 提取电影名称
titles = tree.xpath('//div[@class="info"]/div[@class="hd"]/a/span[@class="title"]/text()')
print(titles)  # 输出:['肖申克的救赎']

2.4每页url规律

# 第1页
'https://movie.douban.com/top250?start=0&filter='# 第2页
'https://movie.douban.com/top250?start=25&filter='# 第3页
'https://movie.douban.com/top250?start=50&filter='# 第4页
'https://movie.douban.com/top250?start=75&filter='# 第5页
'https://movie.douban.com/top250?start=100&filter='# 尾页
'https://movie.douban.com/top250?start=225&filter='

可以发现一个规律

for page in range(1, 11):# 目标urlurl = f'https://movie.douban.com/top250?start={(page - 1) * 25}&filter='

2.5逐条查找所需信息

我们需要一层一层定位所需要的信息,如下图

2.6完整代码

# 导入模块
import pandas as pd
import requests
from lxml import etree
import csvdef crawler_douban():# 请求头信息headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36'}moive_list = []for page in range(1, 11):# 目标urlurl = f'https://movie.douban.com/top250?start={(page - 1) * 25}&filter='# 发送请求, 获取响应res = requests.get(url, headers=headers)# 打印响应信息# print(res.text)# 网页源码html = res.text# 实例化etree对象tree = etree.HTML(html)divs = tree.xpath('//div[@class="info"]')# print(divs)i = 1for div in divs:dic_temp = {}dic_temp['电影中文名'] = ''dic_temp['电影英文名'] = ''dic_temp['电影详情页链接'] = ''dic_temp['导演'] = ''dic_temp['主演'] = ''dic_temp['上映年份'] = ''dic_temp['国籍'] = ''dic_temp['类型'] = ''dic_temp['评分'] = ''dic_temp['评分人数'] = ''dic_temp['评语'] = ''print('>>>>>>>>>>')print(i)print(div)div_temp = div.xpath('./div[@class="hd"]/a')urlx = div_temp[0].get('href')texts = [a.xpath('string(.)').strip() for a in div_temp]print(texts)need_list1 = []for each_text in texts:each_text_list = each_text.split('\n')for each_one in each_text_list:need_list1.append(each_one.replace(' ', ''))div_temp = div.xpath('./div[@class="bd"]')texts = [a.xpath('string(.)').strip() for a in div_temp]need_list2 = []for each_text in texts:each_text_list = each_text.split('\n')for each_one in each_text_list:need_list2.append(each_one.replace(' ', ''))print(need_list1)print(need_list2)dic_temp['电影中文名'] = need_list1[0]dic_temp['电影英文名'] = need_list1[1].replace('\xa0/\xa0', '')dic_temp['电影详情页链接'] = urlxdic_temp['导演'] = need_list2[0].split('xa0\xa0\xa0')[0]print(need_list2[0])try:dic_temp['导演'] = dic_temp['导演'].replace('导演:', '').replace('\xa0\xa0\xa0', '')dic_temp['导演'] = dic_temp['导演'].split('主演:')[0]except:passtry:dic_temp['主演'] = need_list2[0].split('主演:')[1]except:passdic_temp['上映年份'] = need_list2[1].split('\xa0/\xa0')[0]dic_temp['国籍'] = need_list2[1].split('\xa0/\xa0')[1]dic_temp['类型'] = need_list2[1].split('\xa0/\xa0')[2]dic_temp['评分'] = need_list2[7]dic_temp['评分人数'] = need_list2[9]if need_list2[-1] != need_list2[9]:dic_temp['评语'] = need_list2[-1]if dic_temp != {}:print(dic_temp)moive_list.append(dic_temp)i += 1print(f'----------------------第{page}页爬取完成--------------------------------------')print('-----------------------爬虫结束-------------------------------')df = pd.DataFrame(moive_list)df.to_excel('douban_TOP250_moive.xlsx', index=None)return df# 程序入口
if __name__ == "__main__":df = crawler_douban()print(df)

3 数据存储至mysql

3.1新建数据库

使用Navicat新建数据库时,既可通过可视化界面操作,也能直接编写SQL命令完成。

可视化界面操作

编写SQL命令

CREATE TABLE `top250movie` (`update_date` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '更新日期',`feature` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '特征值',`movie_ch` varchar(255) DEFAULT NULL COMMENT '电影中文名',`movie_en` varchar(255) DEFAULT NULL COMMENT '电影英文名',`movie_url` varchar(255) DEFAULT NULL COMMENT '电影详情页链接',`director` varchar(255) DEFAULT NULL COMMENT '导演',`star` varchar(255) DEFAULT NULL COMMENT '主演',`start_year` varchar(255) DEFAULT NULL COMMENT '上映年份',`country` varchar(255) DEFAULT NULL COMMENT '国籍',`type` varchar(255) DEFAULT NULL COMMENT '类型',`rating` varchar(255) DEFAULT NULL COMMENT '评分',`num_ratings` varchar(255) DEFAULT NULL COMMENT '评分人数',`comment` varchar(1000) DEFAULT NULL COMMENT '评语',PRIMARY KEY (`feature`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

3.2编写数据库写入py文件

3.2.1构建1个执行sql语句的函数

定义了一个函数 cost_execute_sql_no_return_value(sql),用于执行 不返回结果 的 SQL 语句(如 INSERTUPDATEDELETE),并处理数据库连接池、事务和错误。

数据库连接池配置

__config = {"host": "localhost",      # MySQL 服务器地址"port": 3306,             # 端口号"user": "root",           # 用户名"password": "dandan1901", # 密码"database": "douban"      # 数据库名
}
  • 定义了 MySQL 的连接参数,包括主机、端口、用户名、密码和数据库名。

初始化连接池

try:pool = mysql.connector.pooling.MySQLConnectionPool(**__config,pool_size=10  # 连接池大小(最多 10 个连接))
except Exception as e:print(e)  # 如果连接池初始化失败,打印错误
  • MySQLConnectionPool:创建一个 MySQL 连接池,pool_size=10 表示最多维护 10 个连接。

  • 异常处理:如果连接池初始化失败(如密码错误、网络问题),捕获异常并打印。

执行 SQL 语句

try:con = pool.get_connection()  # 从连接池获取一个连接cursor = con.cursor()        # 创建游标cursor.execute(sql)          # 执行 SQLcon.commit()                 # 提交事务print(('Successfully insert ' + sql).encode('gbk', 'ignore').decode('gbk', 'ignore'))
except Exception as e:print(e)  # 打印错误信息if "con" in dir():           # 如果连接存在con.rollback()           # 回滚事务print(('Failed insert ' + sql).encode('gbk', 'ignore').decode('gbk', 'ignore'))
finally:if "con" in dir():           # 确保连接被关闭con.close()
  • pool.get_connection():从连接池获取一个可用连接。

  • cursor.execute(sql):执行传入的 SQL 语句。

  • con.commit():如果执行成功,提交事务。

  • con.rollback():如果执行失败,回滚事务。

  • con.close():在 finally 中确保连接被关闭(防止资源泄漏)。

  • 编码处理
    ('Successfully insert ' + sql).encode('gbk', 'ignore').decode('gbk', 'ignore')
    这段代码是为了避免中文字符在打印时出现编码错误(gbk 是 Windows 终端常用编码)。

3.2.2构造一个将dataframe转成sql语句的函数

将 DataFrame 中的数据批量插入/更新到 MySQL 数据库的 top250movie 表中

def write_info_into_db(df):for i in range(df.shape[0]):df.loc[i, '特征值'] = 'TOP' + str(i + 1).zfill(4)df['更新日期'] = str(datetime.datetime.now())# 将数据写入数据库insert_cols = {'update_date': '更新日期','feature': '特征值','movie_ch': '电影中文名','movie_en': '电影英文名','movie_url': '电影详情页链接','director': '导演','star': '主演','start_year': '上映年份','country': '国籍','type': '类型','rating': '评分','num_ratings': '评分人数','comment': '评语',}# df_copy = pd.DataFrame(df)db_list = list(insert_cols.keys())print(db_list)for i in range(df.shape[0]):dbname = 'top250movie'sql = "REPLACE INTO " + dbname + " ("for ix in range(len(db_list)):if ix < len(db_list) - 1:sql = sql + str(db_list[ix]) + ', 'else:sql = sql + str(db_list[ix])sql = sql + ") VALUES ("for ix in range(len(db_list)):each_key = db_list[ix]print(df.loc[i, insert_cols[each_key]])if ix < len(db_list) - 1:sql += "'" + str(df.loc[i, insert_cols[each_key]]) + "'" + ","else:sql += "'" + str(df.loc[i, insert_cols[each_key]]) + "'" + ");"print('>>>>>>>>>>')print(sql)cost_execute_sql_no_return_value(sql)

数据处理

for i in range(df.shape[0]):df.loc[i, '特征值'] = 'TOP' + str(i + 1).zfill(4)  # 生成形如 "TOP0001" 的特征值
  • 为 DataFrame 的每一行添加 特征值 列,格式为 TOP0001TOP0002...(zfill(4) 保证 4 位数字)。

df['更新日期'] = str(datetime.datetime.now())  # 添加当前时间戳
  • 添加 更新日期 列,值为当前时间(字符串格式)。

数据库字段映射

insert_cols = {'update_date': '更新日期',    # 数据库列名: DataFrame 列名'feature': '特征值','movie_ch': '电影中文名','movie_en': '电影英文名','movie_url': '电影详情页链接','director': '导演','star': '主演','start_year': '上映年份','country': '国籍','type': '类型','rating': '评分','num_ratings': '评分人数','comment': '评语',
}
  • 定义数据库列名(key)和 DataFrame 列名(value)的映射关系。

db_list = list(insert_cols.keys())  # 获取数据库列名列表
print(db_list)  # 打印列名(调试用)

生成并执行 SQL

for i in range(df.shape[0]):  # 遍历 DataFrame 每一行dbname = 'top250movie'sql = "REPLACE INTO " + dbname + " ("# 拼接列名部分(如 REPLACE INTO top250movie (update_date, feature, ...))for ix in range(len(db_list)):if ix < len(db_list) - 1:sql += str(db_list[ix]) + ', 'else:sql += str(db_list[ix])sql += ") VALUES ("# 拼接值部分(如 VALUES ('2023-01-01', 'TOP0001', ...))for ix in range(len(db_list)):each_key = db_list[ix]print(df.loc[i, insert_cols[each_key]])  # 打印当前值(调试用)if ix < len(db_list) - 1:sql += "'" + str(df.loc[i, insert_cols[each_key]]) + "', "else:sql += "'" + str(df.loc[i, insert_cols[each_key]]) + "');"print('>>>>>>>>>>')print(sql)  # 打印完整 SQL(调试用)cost_execute_sql_no_return_value(sql)  # 执行 SQL
  • REPLACE INTO:如果主键冲突,则删除旧记录并插入新记录(类似 INSERT + DELETE)。

  • 动态生成 SQL:根据 db_list 和 DataFrame 的值拼接 SQL 语句。

  • 执行 SQL:调用 cost_execute_sql_no_return_value(sql)(前文定义的函数)执行。

3.2.3完整代码

# 导入模块
import datetimeimport mysql.connector.pooling
import pandas as pd
import requests
from lxml import etreedef cost_execute_sql_no_return_value(sql):__config = {"host": "localhost","port": 3306,"user": "root","password": "faw-vw.1901","database": "douban"}try:pool = mysql.connector.pooling.MySQLConnectionPool(**__config,pool_size=10)except Exception as e:print(e)try:con = pool.get_connection()cursor = con.cursor()cursor.execute(sql)con.commit()print(('Successfully insert ' + sql).encode('gbk', 'ignore').decode('gbk', 'ignore'))except Exception as e:print(e)if "con" in dir():con.rollback()print(('Failed insert ' + sql).encode('gbk', 'ignore').decode('gbk', 'ignore'))finally:if "con" in dir():con.close()def crawler_douban():# 请求头信息headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36'}moive_list = []for page in range(1, 11):# 目标urlurl = f'https://movie.douban.com/top250?start={(page - 1) * 25}&filter='# 发送请求, 获取响应res = requests.get(url, headers=headers)# 打印响应信息# print(res.text)# 网页源码html = res.text# 实例化etree对象tree = etree.HTML(html)divs = tree.xpath('//div[@class="info"]')# print(divs)i = 1for div in divs:dic_temp = {}dic_temp['电影中文名'] = ''dic_temp['电影英文名'] = ''dic_temp['电影详情页链接'] = ''dic_temp['导演'] = ''dic_temp['主演'] = ''dic_temp['上映年份'] = ''dic_temp['国籍'] = ''dic_temp['类型'] = ''dic_temp['评分'] = ''dic_temp['评分人数'] = ''dic_temp['评语'] = ''print('>>>>>>>>>>')print(i)print(div)div_temp = div.xpath('./div[@class="hd"]/a')urlx = div_temp[0].get('href')texts = [a.xpath('string(.)').strip() for a in div_temp]print(texts)need_list1 = []for each_text in texts:each_text_list = each_text.split('\n')for each_one in each_text_list:need_list1.append(each_one.replace(' ', ''))div_temp = div.xpath('./div[@class="bd"]')texts = [a.xpath('string(.)').strip() for a in div_temp]need_list2 = []for each_text in texts:each_text_list = each_text.split('\n')for each_one in each_text_list:need_list2.append(each_one.replace(' ', ''))print(need_list1)print(need_list2)dic_temp['电影中文名'] = need_list1[0]dic_temp['电影英文名'] = need_list1[1].replace('\xa0/\xa0', '')dic_temp['电影详情页链接'] = urlxdic_temp['导演'] = need_list2[0].split('xa0\xa0\xa0')[0]print(need_list2[0])try:dic_temp['导演'] = dic_temp['导演'].replace('导演:', '').replace('\xa0\xa0\xa0', '')dic_temp['导演'] = dic_temp['导演'].split('主演:')[0]except:passtry:dic_temp['主演'] = need_list2[0].split('主演:')[1]except:passdic_temp['上映年份'] = need_list2[1].split('\xa0/\xa0')[0]dic_temp['国籍'] = need_list2[1].split('\xa0/\xa0')[1]dic_temp['类型'] = need_list2[1].split('\xa0/\xa0')[2]dic_temp['评分'] = need_list2[7]dic_temp['评分人数'] = need_list2[9]if need_list2[-1] != need_list2[9]:dic_temp['评语'] = need_list2[-1]if dic_temp != {}:print(dic_temp)moive_list.append(dic_temp)i += 1print(f'----------------------第{page}页爬取完成--------------------------------------')print('-----------------------爬虫结束-------------------------------')df = pd.DataFrame(moive_list)df.to_excel('douban_TOP250_moive.xlsx', index=None)return dfdef write_info_into_db(df):for i in range(df.shape[0]):df.loc[i, '特征值'] = 'TOP' + str(i + 1).zfill(4)df['更新日期'] = str(datetime.datetime.now())# 将数据写入数据库insert_cols = {'update_date': '更新日期','feature': '特征值','movie_ch': '电影中文名','movie_en': '电影英文名','movie_url': '电影详情页链接','director': '导演','star': '主演','start_year': '上映年份','country': '国籍','type': '类型','rating': '评分','num_ratings': '评分人数','comment': '评语',}# df_copy = pd.DataFrame(df)db_list = list(insert_cols.keys())print(db_list)for i in range(df.shape[0]):dbname = 'top250movie'sql = "REPLACE INTO " + dbname + " ("for ix in range(len(db_list)):if ix < len(db_list) - 1:sql = sql + str(db_list[ix]) + ', 'else:sql = sql + str(db_list[ix])sql = sql + ") VALUES ("for ix in range(len(db_list)):each_key = db_list[ix]print(df.loc[i, insert_cols[each_key]])if ix < len(db_list) - 1:sql += "'" + str(df.loc[i, insert_cols[each_key]]) + "'" + ","else:sql += "'" + str(df.loc[i, insert_cols[each_key]]) + "'" + ");"print('>>>>>>>>>>')print(sql)cost_execute_sql_no_return_value(sql)# 程序入口
if __name__ == "__main__":# 爬取数据df = crawler_douban()print(df)# 将数据写入数据库write_info_into_db(df)

展示结果如下

4 总结

此处省略1万字,感谢各位看到最后,最后附上代码信息,数据库也在文件中,百度网盘链接如下

通过网盘分享的文件:项目工坊_豆瓣爬虫
链接: https://pan.baidu.com/s/1cY8plsXfVYl8NuhBixVrTQ?pwd=y131 提取码: y131

http://www.dtcms.com/wzjs/185016.html

相关文章:

  • 十大最耐看装修风格企业网站优化方案案例
  • 网站建设合同 保密条款推广平台软件有哪些
  • 电子商务网站开发数据库表格百度云app下载安装
  • wordpress 产品展示 插件seo优化网络
  • 如何做财经网站沧州百度推广公司
  • 有哪些html代码大全搜索优化seo
  • 招商网站建设方案搜索引擎优化的核心是
  • 网站数据统计怎么做上海整站seo
  • 洛阳兼职网站优化推荐
  • 网站建设的功能模块长春网站建设平台
  • 做网站做什么公司好广州谷歌推广
  • 动态网站没有数据库怎么做seo常用优化技巧
  • 蜜蜂vp加速器七天试用广东seo推广
  • 江苏华能建设集团有限公司网站外链工具在线
  • wordpress怎么充值武汉seo公司
  • 做网站 博客十大中文网站排名
  • 收费小说网站怎么做网络推广是网络营销的基础
  • 自己做一元购网站线上推广有哪些
  • 网站优化入门免费教程关键词优化报价推荐
  • 可信网站多少钱怎么投稿各大媒体网站
  • 怎样做网站认证吸引人的软文
  • 怎么做免费的网站推广武汉seo创造者
  • 论坛门户网站建设运营费用如何将网站的关键词排名优化
  • 程序员 做 个人网站营业推广方式
  • 平面设计速成培训机构seo点击工具
  • 怎样手机做网站教程江苏网站建站系统哪家好
  • 做网站卖东西赚钱百度服务中心人工24小时电话
  • 网站建设销售怎么做网站推广应该坚持什么策略
  • 网站系统是一个典型的如何搭建自己的网站
  • 有哪些网站可以做问卷调查浏览器网页版入口