范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

Python爬虫几个步骤教你写入mysql数据库

  Python爬虫几个步骤教你写入mysql数据库
  Python爬虫实现爬取网站中的数据并存入MySQL数据库中,在爬取的时候总要涉及到数据持久化存储,当然有很多中存储的方式,简单点的有excel、txt、json、csv等等。存入mysql我觉的有好多操作空间,如果是开发python后端也可以熟悉一下sql语句,存入数据库的方法也是试了些许网上一些方法,现在把完整功能供大家参考。
  直接搜索 phpStudy安装即可,按照下图配置数据库。用户名密码自行设置,然后返回首页启动即可。
  pip install pymysql
  打开刚安装的phpstudy安装一个mysql客户端连接,数据库是本地的host可以填 127.0.0.1 或 localhost用户名密码是上面设置的
  MySQL创建对应的表CREATE TABLE `text_archives`  (   `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT "ID",   `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT "" COMMENT "链接",   `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT "" COMMENT "标题",   `image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT "" COMMENT "图片",   `keywords` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "关键描述",   `description` varchar(600) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT "" COMMENT "内容描述",   `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT "内容",   `weigh` int(10) NOT NULL DEFAULT 0 COMMENT "权重",   `createtime` bigint(16) NOT NULL DEFAULT 0 COMMENT "创建时间",   `updatetime` bigint(16) NOT NULL DEFAULT 0 COMMENT "更新时间",   `deletetime` bigint(16) NULL DEFAULT NULL COMMENT "删除时间",   PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 2692 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = "内容表" ROW_FORMAT = Dynamic;  SET FOREIGN_KEY_CHECKS = 1;
  构造 SQL 语句的字符串 sql ,然后通过 cursor.excute(sql) 执行,下面简单的封装,直接复制即可用。import pymysql   class Mysql(object):     def __init__(self):         self._connect = pymysql.connect(             host="127.0.0.1",             user="test",             password="######",             database="test",             charset="utf8mb4",             cursorclass=pymysql.cursors.DictCursor         )         self._cursor = self._connect.cursor()      def inset_db(self, table_name, insert_data):         try:             data = self.get_mysql_data(data=insert_data)             fields = data[0]             values = data[1]             sql = "INSERT INTO {table_name}({fields}) values ({values})".format(table_name=table_name, fields=fields,                                                                                 values=values)             self._cursor.execute(sql)             self._connect.commit()         except Exception as e:             self._connect.rollback()  # 如果这里是执行的执行存储过程的sql命令,那么可能会存在rollback的情况,所以这里应该考虑到             print("数据插入失败,失败原因:", e)             print(insert_data)         else:             # self.db_close()             return self._cursor.lastrowid      def update_db(self, table_name, update_data, wheres=None):         try:             if wheres is not None:                 sql = "UPDATE {table_name} SET {update_data} WHERE {wheres}".format(                     table_name=table_name,                     update_data=update_data,                     wheres=wheres                 )             else:                 sql = "UPDATE {table_name} SET {update_data}".format(                     table_name=table_name,                     update_data=update_data)             self._cursor.execute(sql)             self._connect.commit()         except Exception as e:             print("更新失败:", e)             return False         else:             # self.db_close()             return True      def delete_db(self, table_name, wheres):         try:             # 构建sql语句             sql = "DELETE FROM {table_name} WHERE {wheres}".format(table_name=table_name, wheres=wheres)             self._cursor.execute(sql)             self._connect.commit()         except Exception as e:             print("删除失败:", e)             return False         else:             # self.db_close()             return True      def select_db(self, table_name, fields, wheres=None, get_one=False):         try:             if wheres is not None:                 sql = "SELECT {fields} FROM {table_name} WHERE {wheres}".format(                     fields=fields,                     table_name=table_name,                     wheres=wheres                 )             else:                 sql = "SELECT {fields} FROM {table_name}".format(fields=fields, table_name=table_name)             self._cursor.execute(sql)             self._connect.commit()             if get_one:                 result = self._cursor.fetchone()             else:                 result = self._cursor.fetchall()         except Exception as e:             print("查询失败", e)             return None         else:             # self.db_close()             return result      def get_mysql_data(self, data):         fields = ""         insert_data = ""         for k, v in data.items():             fields = fields + k + ","             insert_data = insert_data + """ + str(v) + """ + ","         fields = fields.strip(",")         insert_data = insert_data.strip(",")         return [fields, insert_data]      def db_close(self):         self._cursor.close()         self._connect.close()
  这次简单点咱们用xpath就行,有一个小技巧咱们在爬取的网页打开开发都模式F12.如下图红框复制第一个或都第二个就行。
  下面代码是实现爬取数据然后存入数据库类,大家可参考from model.nav import Nav import requests from urllib import parse from lxml import etree from fake_useragent import UserAgent from lib.reptile import Reptile import json   class Common(object):     def __init__(self, params):         self.url = params["url"]         self.params = params         self.blog = 1        def get_header(self):         ua = UserAgent()         headers = {             "User-Agent": ua.random         }         return headers      def get_html(self, url):         # 在超时间内,对于失败页面尝试请求三次         if self.blog <= 3:             try:                 res = requests.get(url=url, headers=self.get_header(), timeout=3)                 res.encoding = res.apparent_encoding                 html = res.text                 return html             except Exception as e:                 print(e)                 self.blog += 1                 self.get_html(url)     def json_insert_data(self, params):       category_id = self.insert_category(cname=params["category_name"], pid=params["pid"], icon="")       print("分类插入成功:{}".format(params["category_name"]))       if category_id:           url = params["url"]           title = params["title"]           image = params["image"]           description = params["description"]           keywords = params["keywords"]           content = params["content"]           self.insert_archives(category_id, url, title, image, description, keywords, content)           print("内容插入成功:{}".format(title))           print("------------------------------------------------------------")     def get_item(self, xpath_html):         item_list = xpath_html.xpath(self.params["item_xpath"])         print(item_list)         for row in item_list:             url_list = row.xpath(self.params["url_xpath"])             if len(url_list) > 0:                 self.get_content(url_list[0])      def get_content(self, url):         print("正在抓取链接:{}".format(url))         domain = parse.urlparse(url).netloc         d_domain = parse.urlparse(self.url).netloc         if domain == d_domain:             html = self.get_html(url)             self.reptile.blog = 1             if html:                 p = etree.HTML(html)                 title = self.get_conmon_content(p, self.params["title_xpath"])                 print("标题为:{}".format(title))                 category_name = self.get_conmon_content(p, self.params["category_xpath"])                 print("分类为:{}".format(category_name))                 image = self.get_conmon_content(p, self.params["image_xpath"])                 print("图片为:{}".format(image))                 link = self.get_conmon_content(p, self.params["link_xpaht"])                 print("链接为:{}".format(link))                 description = self.get_conmon_content(p, self.params["description_xpath"])                 print("描述为:{}".format(description))                 keywords = self.get_conmon_content(p, self.params["keywords_xpath"])                 print("关键描述:{}".format(keywords))                 content = self.get_conmon_content(p, self.params["content_xpath"])                 print("内容为:{}".format(content))                 params = {                     "pid": 158,                     "title": title,                     "category_name": category_name,                     "image": image,                     "url": link,                     "description": description,                     "keywords": keywords,                     "content": content,                 }                 if title and category_name and link:                     self.json_insert_data(params)#存入数据库      def get_conmon_content(self, xpath_html, xpath):         content_list = xpath_html.xpath(xpath)         content = ""         if len(content_list) > 0:             content = content_list[0].strip()         return content      def run(self):         print("url:{}".format(self.url))         html = self.get_html(self.url)         if html:             p = etree.HTML(html)             self.get_item(p)  #爬取的xpath params = {     "url": "https://www.widiz.com/", #爬取url     "url_xpath": ".//a[1]/@href",     "title_xpath": "/html/body/p[1]/p[2]/p[3]/p/p[3]/p/h1/text()",     "category_xpath": "/html/body/p[1]/p[2]/p[3]/p/p[3]/p/a[1]/text()",     "image_xpath": "/html/body/p[1]/p[2]/p[3]/p/p[2]/p/img/@src",     "link_xpaht": "/html/body/p[1]/p[2]/p[3]/p/p[3]/p/p/p[1]/span/a/@href",     "description_xpath": "/html/head/meta[10]/@content",     "keywords_xpath": "/html/head/meta[5]/@content",     "content_xpath": "/html/body/p[1]/p[2]/p[3]/main/p[1]/p/p[1]/p/p[2]/text()" }  Common(params).run()
  最终效果:

科技日报我科学家实现多模量子态的长时间存储来源安徽省科学技术厅媒体聚焦记者11月9日从中国科学技术大学获悉,该校郭光灿院士团队的史保森丁冬生课题组利用磁场操控技术结合钟态制备的方法,实现了基于冷原子系综的光子高维轨道角动量爆炸性消息马斯克称推特可能会在明年申请破产周四,埃隆马斯克(ElonMusk)在推特(Twitter)的任期变得更加坎坷。据报道,他在一次紧急全员会议上告诉员工,他不排除公司明年申请破产的可能性。据theInformati2022年世界互联网大会蓝皮书发布数字经济为全球经济增长注入新动能2022年世界互联网大会蓝皮书新闻发布会于9日在浙江乌镇举行。自2017年起,蓝皮书连续六年面向全球发布,既是世界互联网大会的一项重要理论和实践研究成果,也是国际互联网研究领域的一誉衡药业控股股东被法院裁定终止重整程序并宣告破产,可能会导致公司控制权发生变化誉衡药业11月11日公告,公司收到哈尔滨中院民事裁定书,相关情况公告如下,哈尔滨中院根据控股股东誉衡集团管理人的申请,依照中华人民共和国企业破产法第八十八条之规定,于2022年11智利南美天涯之国,婚姻高度自由,开放程度令人瞠目结舌头条创作挑战赛智利地图智利共和国位于南美洲西南部,安第斯山脉西麓。东同阿根廷为邻,北与秘鲁玻利维亚接壤,西临太平洋,南与南极洲隔海相望,国土面积756715平方公里,智利共分为16重磅!中国入境变53,附全球85国(地区)入境政策汇总重磅!就在刚刚,国务院官宣国内防疫政策调整!重点如下对入境人员,将7天集中隔离3天居家健康监测调整为5天集中隔离3天居家隔离。取消入境航班熔断机制,并将登机前48小时内2次核酸检测女子山上摘了一株花竟被刑拘?这些植物千万别碰近日一女子出门游玩在山崖上发现一株美丽小花她用手机搜索确认了花的品种随即将其采摘回家还拍照发了微博炫耀结果不到一天时间警方就找上门了原来这株花叫槭叶铁线莲是国家二级保护植物该女子因沈阳棋盘山一日游规划,如果是第一次来沈阳,3条路线一定要收藏文鹏鹏走江湖沈阳棋盘山,是沈阳周边的大型风景区之一。一年四季棋盘山有不同的样子,比如春季这里是踏青郊游的好地方,夏季这里是人们避暑胜地之一,秋季这里不同品种的树木,将这里装扮的像童图集稻花香里说丰年,这个季节中山南朗最多彩夏末秋初,一场丰收正在中山市南朗街道左步村中酝酿着,村中连片的稻田即将进入成熟期。游客在左步村稻田徒步。南方李姗恒拍摄稻花香里说丰年,这是视觉的体验,也是一种嗅觉的体验。连片稻田化他为了皇位装疯卖傻36年,摇身一变成为一代贤君在中国古代,皇帝是无数人梦寐以求的职业,为了能荣登皇位,很多人不择手段,所用的手段只有你想不到,没有他们做不到的,最直接的就是奋起一战,夺得皇位,失败了则人头落地,正验证着高风险高和坤贪污了那么多的钱,乾隆为什么不杀了他?关键是和珅有个长处说起清朝,那必然会想起康乾盛世,当然,在历史上,清朝有名的大臣们也不少,但是在这些有名的大臣当中,最有名的莫过于乾隆的大臣和坤了。说起和坤,对于不了解历史的人来说,那第一印象肯定是
原神提瓦特的宿敌之战,万叶和散兵的恩怨情仇,该放下了前段时间被散兵频繁的刷屏,一个洗白问题又重新出现在视线当中。而lumie发布了2。8上半部分卡池信息,万叶再一次被卷入,这次不讨论万叶复刻是否入手的问题,因为入不入手相信大家心里早遗憾的输掉,中国女排212022世界女排联赛一场焦点大战,中国女排PK美国女排,第一局的较量,中国队遗憾的输掉,2125惜败!王唯漪的一传质量太差,被对手连续冲击,不得不说,美国队太强了啊。进入到第二周,夏至不理发,还有哪些习俗和禁忌?下雨好还是晴天好?农谚咋说导读夏至将至,为什么夏至不能理发呢?还有哪些习俗和禁忌?夏至是下雨好,还是晴天好?农村谚语是咋说的?夏至,又叫夏至节,是24节气的第10个节气,是太阳运行到黄经90度处赤道上空的时克罗和雷蒙,为何是一对宿敌索罗斯雷蒙,网页游戏赛尔号及其衍生作品中的角色,通称雷蒙教官,赛尔号的练兵导师,军衔少校,官方小说英雄赛尔号2第一部内身为赛尔号总教官的他有一个名为T博士的老师,在克洛斯星大学毕业中国正式进入三航母时代我国第三艘航母下水命名仪式17日上午在中国船舶集团有限公司江南造船厂举行。中共中央政治局委员中央军事委员会副主席许其亮出席仪式。11点左右,下水命名仪式开始,全场齐唱中华人民共和国美澳反华计划又将夭折,南太岛国不买账,多国出面为中国发声随着综合国力的增强,中国对南太地区的投资呈现出递增的态势。这原本是再正常不过的事情,然而为了达到遏制中国发展的目的,美国一直在挑唆澳大利亚与中国作对,还为此煞有介事地搞起了所谓的南浓眉官宣加盟电竞战队!詹姆斯仍在苦练,网友疯狂diss浓眉湖人球星安东尼戴维斯更新个人推特,在推文中他宣布已加盟北美电竞俱乐部FaZeClan旗下的使命召唤战队NukeSquad。NukeSquad也对浓眉的加入表示欢迎。湖人的另一位当家10位国际顶尖神颜!从球花到法兰西玫瑰,统一了全球审美美人无论在什么时代都是饱受关注的,毕竟谁不喜欢看那些美丽又让人赏心悦目的美女呢。无论中外总有几位神颜级别的女星,能够让人过目不忘。而国际上就有这么几位女神级别的明星,他们的美不仅惊蒂姆直播吧6月18日讯据日刊体育消息,前澳大利亚国脚蒂姆卡希尔近日接受采访时谈到了澳大利亚通过洲际附加赛晋级世界杯正赛,他表示对此感到非常高兴,同时也表示球队要正视自己的实力。谈澳大利蒋介石临终遗言,说出囚禁张学良多年原因,宋美龄听后潸然泪下1936年西安事变后,杨虎城和张学良这两个主要当事人就被蒋介石囚禁了起来,在新中国成立前夕,杨虎城将军被蒋介石狠心杀害,而张学良却逃过一劫被国民党转运到台湾,关押了大半辈子。直到1瓦拉内接下来是一个全新的赛季对新任主帅充满期待近日,瓦拉内接受了曼联官网的采访,在采访中他谈到了对新赛季的展望。当被问道对于季前赛的看法以及关于新赛季的展望时,瓦拉内说道接下来的一个赛季是一个全新的赛季,并且将是一个全新的开始