Python爬虫系统化学习(4)
在之前的学习过程中,我们学习了如何爬取页面,对页面进行解析并且提取我们需要的数据。
在通过解析得到我们想要的数据后,最重要的步骤就是保存数据。
一般的数据存储方式有两种:存储在文件或者数据库中。在本篇博客中我会细致的讲解从零基础到血会存储在txt或者csv文件,以及通过PHPstudy去保存数据。
Python文件存储
首先我们来写一组最简单的代码,实现的功能是打开C盘目录下的a.txt,并且写入"hello python",然后关闭文件。代码如下:
content="hello python" with open('C:\\a.txt',"a+") as f: f.write(content) f.close()
这里有个细节是C:\是两个反斜杠,这是因为转义的原因。通常地址的三种表现形式:
open('D:\\Data\\a.txt',"a+") open(r'D:\Data\a.txt',"a+") open('D:/Data/a.txt',a+)
一个重点是我们要知道文件的本质是句柄,他是文件的唯一标识符。我们每次打开一个文件,都会在系统中生成一个用数字表示的句柄,这串数字表示应用程序所代表的一系列内容。我们在记事本内写东西就是代表着我们对句柄所代表的内容进行输入。
我们可以查看下上述代码打开a.txt文件的句柄,在原有代码之下输入一下代码:
print(f) #输出内容:<_io.TextIOWrapper name='D:\\a.txt' mode='a+' encoding='cp936'> 此后对f的操作就是对a.txt的操作
所以对文件的操作都是在句柄上进行的,常用的文件处理方法及属性列表如下
方法:
一个注意点是句柄用完后一定要关闭,不然在大量文本情况下会大量消耗系统内存
file.close()
但是使用with open 就会自动关闭这是要注意到的。
将字符文本保存到文件中,可读性是很重要的,以列的形式表示有助于我们阅读,假如我的对象有4个变量,那如何将这四个变量有序的存储在txt文本呢?
name=['wang','zhou','sudong'] num=['1','2','3'] house=['nanjing','shanghai','guangdong'] year=['19','20','21'] with open("D:/a.txt","a+") as f: for i in range(0,3): thing='\t'.join((name[i],num[i],house[i],year[i])) f.write(thing) f.write('\n')
通过'\t'.join就可以实现有序的保存
CSV文件存储
Python对CSV文件的存储及其简单,以行的形式读取CSV代码如下:
import csv with open('a.csv',"r",encoding='utf-8') as fileread: csv_reader=csv.reader(fileread) for row in csv_reader: print(row)
csv以行的形式写文件:
import csv out_put=['2','0','2','1'] with open('1.csv','a+',encoding='UTF-8',newline='') as csvwrite: w=csv.writer(csvwrite) w.writerow(out_put)
此外除了使用文件和csv之外我们还可以使用数据库进行保存。
由于是从零基础去学习爬虫的存储,所以数据库的安装是很有必要说一下的
这里我比较喜欢用小皮面板里的数据库,让我们来看看数据库如何安装以及数据库的基本操作。
首先在网址https://www.xp.cn下载小皮面板,打开小皮面板并在phpstudy_pro/Extension找到相应的Mysql目录并且进入,然后打开CMD控制台:
输入
mysql -u root -p
password:root
连接到数据库
连接到数据库后我们需要了解下数据库的基本命令:
#显示数据库 show databases; #创建数据库 CREATE DATABASE scraping #使用数据库 USE scraping #创建数据表 CREATE TABLE urls( id INT NOT NULL AUTO_INCREMENT, url VARCHAR(1000) NOT NULL, content VARCHAR(4000) NOT NULL, crated_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ); #查看数据表的结构 DESCRIPBE urls; #插入数据 INSERT INTO urls (url,content) VALUES ("www.baidu.com","嘿嘿嘿"); #查询数据 SELECT * FROM urls WHERE id=1; #查询部分数据 SELECT url,content FROM urls WHERE id=1; #删除某些数据 DELETE FROM urls WHERE url="www.baidu.com" #更新某些数据 UPDATE urls SET url="www.google.com",content="Google" WHERE id=2;
通过Python操作Mysql数据库需要事先用PIP下载好pymysql
#coding:utf-8 import pymysql #连接到数据 Dbcursor=pymysql.connect(host="127.0.0.1",user="root",password="root1234",database="scraping") cursor=Dbcursor.cursor() sql="""INSERT INTO urls (url,content) VALUES ('www.baidu.com','测试代码1')""" try: cursor.execute(sql) Dbcursor.commit() except: Dbcursor.rollback() Dbcursor.close()
逻辑:通过连接到数据库然后通过cursor()方法获得数据库操作的游标,继而对数据库执行sql语句的操作。
实战:
#coding:utf-8 import requests import re import pymysql from bs4 import BeautifulSoup link="https://nj.ke.com/ershoufang/pg" headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0","Host": "nj.ke.com"} db=pymysql.connect(host="127.0.0.1",user="root",password="root1234",database="house_selling") cursor=db.cursor() sql="""CREATE TABLE house( `id` INT NOT NULL AUTO_INCREMENT, `name` VARCHAR(1000) NOT NULL, `house_info` VARCHAR(1000) NOT NULL, `total_money` VARCHAR(1000) NOT NULL, `aver_money` VARCHAR(1000) NOT NULL, `address` VARCHAR(1000) NOT NULL, `created_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ); """ cursor.execute(sql) for i in range(1,999): link_=link+str(i)+'/' r=requests.get(link_,headers=headers) soup=BeautifulSoup(r.text,"html.parser") houst_list=soup.find_all('li',class_='clear') for house in houst_list: name=house.find('div',class_='title').a.text.strip() houst_info=house.find('div',class_='houseInfo').text.strip() houst_info=re.sub('\s+','',houst_info) total_money=str(house.find('div',class_='totalPrice').span.text.strip())+'万' aver_money=str(house.find('div',class_='unitPrice').span.text.strip()) adderess=house.find('div',class_='positionInfo').a.text.strip() print(name,houst_info,total_money,aver_money,adderess) sql="""INSERT INTO house (name,house_info,total_money,aver_money,address) values (%s,%s,%s,%s,%s)""" values=(name,houst_info,total_money,aver_money,adderess) cursor.execute(sql,values) #把数据库进行更新,如果缺少,代码就会报错 db.commit() cursor.close() db.close()
通过查看数据库发现数据库已经写入,
本文总结:通过本篇文章,我们学到了通过Python进行文件处理,可以将文件写入txt,csv文本,甚至写入到数据库,其中最关键的就是写入到数据库里,通过将爬取到的数据库写入到数据库里,我们可以创造更多有价值的东西,包括可视化之类的。至此爬虫的三部分包括获取、解析、存储已经讲完了。但是后面多线程的爬虫、分布式爬虫的内容才是更有魅力的。