python新手爬虫练习(二)-编码

本文是Python新手爬虫的第二部分,主要讲述如何确定爬虫的基本框架,包括数据库操作和网页爬取。作者将程序分为novelsql类(处理数据库)和novel类(处理网页)。在数据库操作中,介绍了创建表、添加和查询数据的基本步骤。而在网页爬取部分,详细阐述了如何获取和处理飞卢小说网站的内容,包括选择要爬取的数据、存储和查询数据库。
摘要由CSDN通过智能技术生成

一、确定基本框架

1.确定基本分类

首先我所要编写的程序虽然简单,但因需要多次对数据库进行添加和查询,所以我将整个程序分为了两个py类:一个novelsql类用于编写对数据库操作的代码块;
其余的对网页的爬取和分析在一个novel类中。按说应该把爬取和分析分成两个类,但本程序代码简单并且不多,所以就没有分开了。代码分类

2.确定基本功能

该程序在我的想法中应具有以下的基本功能:
1.提供大的小说分类目录供选择
2.提供查询多页和特定页中的小说列表
3.提供下载特定小说的全部免费章节,并对所下载的内容进行简单的分类和调整下载文本格式(因为从网下爬下来的小说章节没有进行分页且有的语句过长,从而在记事本中查看需要使用者自己去横向的拉会很麻烦。),同时保存小说的封面图片。
基本上就这些功能,看着是不是很简单,很轻松,是不是觉得我很low?对我就是很low,你能怎么办。反正我就写了这些功能(- -!)

二 、代码编写

1.数据库操作

因为两个类中对数据库的操作要简单,所以我们先来编写对数据库的操作。首先我要明白这个类中的代码基本是供另一个类来调用的,所以我们在编写代码是应写在函数中。在py文件中导入另一个py类时,如果代码写没有写在函数中,那在加载你的py类时就会直接先将这些代码进行运行
首先我们需要导入mysql的控制

import mysql.connector

我们需要对数据库作的操作有创建表,添加,查询。
创建表的代码

def createtable(tablename,i):
    mydb=mysql.connector.connect(
         host = "localhost",
         user = "root",
         passwd = "",
         database=database(i))
    mycursor=mydb.cursor()
    sql1="DROP TABLE IF EXISTS "+tablename
    sql="CREATE TABLE IF NOT EXISTS "+tablename+"(Id INT auto_increment ,num INT,t_Type VARCHAR(255),NovelName VARCHAR(25),Url VARCHAR(255), PRIMARY KEY(Id,num,NovelName))"
    mycursor.execute(sql1)
    mycursor.execute(sql)
    mycursor.close()
    mydb.close()

其中的mysql.connector.connect(host,user,passwd,database)是对数据库创建链接,里面有着四个参数。host表示你所链接数据库的地址(这里我连接的是本地服务器,所以之是localhost);user是你访问数据库的用户名(我用的是默认用户名root);passwd是你访问数据库的密码(我没有所以用的空);database是你所访问的数据库名称。

mycursor=mydb.cursor()

这是在获取数据库游标,方便之后对sql语句的进行操作。在对sql语句进行重组时我用的是字符串拼接,这样存在一个很严重的问题——sql注入攻击。我想过取用占位符来占位但python好像不支持,如果有各位有什么好的方法请一定私信我。
向表中添加数据的代码为:

def adddata(tablename,t_type,novelname,url,i):
    mydb=mysql.connector.connect(
         host = "localhost",
         user = "root",
         passwd = "",
         database=database(i))
    mycursor=mydb.cursor()
    sql1="SELECT NovelName FROM "+tablename+" WHERE NovelName='"+novelname+"'"
    mycursor.execute(sql1)
    re=mycursor.fetchall()
    if(re == []):
        sql="INSERT INTO "+tablename+"(num,t_Type,NovelName,Url)VALUES ("+"1"+",'"+t_type+"','"+novelname+"','"+url+"') "
        mycursor.execute(sql)
        mydb.commit()
    mycursor.close()
    mydb.close()

查询的部分分两种,一种为对数据库查询表名。代码如下:

def sqlquery(i):
    mydb=mysql.connector.connect(
    host = "localhost",
    user = "root",
    passwd = "",
    database=database(i))
    mycursor=mydb.cursor()
    mycursor.execute("show tables")
    return mycursor.fetchall()

另一种是对表中的数据按需查询。

def query(tablename,name,i,condition,n):
    mydb=mysql.connector.connect(
         host = "localhost",
         user = "root",
         passwd = "",
         database=database(n))
    mycursor=mydb.cursor()
    if i==0:
        sql="SELECT "+name+" FROM "+tablename
    else:
        sql="SELECT "+name+" FROM "+tablename+" WHERE NovelName='"+condition+"'"
    mycursor.execute(sql)
    return mycursor.fetchall()

数据库的整体代码:

import mysql.connector

def database(i):
    database=("feilu","feilu2")
    return database[i]

def createtable(tablename,i):
    mydb=mysql.connector.connect(
         host = "localhost",
         user = "root",
         passwd = "",
         database=database(i))
    mycursor=mydb.cursor()
    sql1="DROP TABLE IF EXISTS "+tablename
    sql="CREATE TABLE IF NOT EXISTS "+tablename+"(Id INT auto_increment ,num INT,t_Type VARCHAR(255),NovelName VARCHAR(25),Url VARCHAR(255), PRIMARY KEY(Id,num,NovelName))"
    mycursor.execute(sql1)
    mycursor.execute(sql)
    mycursor.close()
    mydb.close()

def adddata(tablename,t_type,novelname,url,i):
    mydb=mysql.connector.connect(
         host = "localhost",
         user = "root",
         passwd = "",
         database=database(i))
    mycursor=mydb.cursor()
    sql1="SELECT NovelName FROM "+tablename+" WHERE NovelName='"+novelname+"'"
    mycursor.execute(sql1)
    re=mycursor.fetchall()
    if(re == []):
        sql="INSERT INTO "+tablename+"(num,t_Type,NovelName,Url)VALUES ("+"1"+",'"+t_type+"','"+novelname+"','"+url+"') "
        mycursor.execute(sql)
        mydb.commit()
    mycursor.close()
    mydb.close()

def query(tablename,name,i,condition,n):
    mydb=mysql.connector.connect(
         host = "localhost",
         user = "root",
         passwd = "",
         database=database(n))
    mycursor=mydb.cursor()
    if i==0:
        sql="SELECT "+name+" FROM "+tablename
    else:
        sql="SELECT "+name+" FROM "+tablename+" WHERE NovelName='"+condition+"'"
    mycursor.execute(sql)
    return mycursor.fetchall()

def sqlquery(i):
    mydb=mysql.connector.connect(
    host = "localhost",
    user = "root",
    passwd = "",
    database=database(i))
    mycursor=mydb.cursor()
    mycursor.execute("show tables")
    return mycursor.fetchall()

可能会有小伙伴说我的代码怎么还有一个数据库的选择。这是因为我对两个库进行了分别的处理。要说为什么不用一个…我懒啊,用一个时会存在一些不方便。

2.网页爬取

首先是页面代码需要导入的模块有

import requests
import bs4
import urllib.request
import os
import stat
import chardet
import re
import novelsql
import lxml.html
import webbrowser

导入后我们先来看看飞卢的主页。在这里插入图片描述在这里插入图片描述
首先选择我们要爬取的内容,在此我用箭头标注的就是我本次程序所爬的内容。之所以不爬完,是因为太耗时间而且其他列表的爬取是一样的,所以想添加的小伙伴可以自行添加。在这里我是讲爬取的内容存到数据库,应为当时没有提前想好所以在储存时有点失误,我在项目中是直接创建以列表名为表名的表,然后再增加数据,但这样在现在看来有问题,不应该分如此多的表而是应该在表中去创建属性来区分,这样我也不需要用两个数据库。(没事我会在寒假去完善的。)
那么来获取的代码和结果如图:

在这里插入图片描述
在这里插入图片描述
因为我基本是将代码进行了封装。所以我解释一下函数的意思,具体代码后面一次会给出。第一个是根据URL去获取网页的数据。第二个是根据soup去将导航中选项与其所对应的网址存入数据库。(注意:飞卢中的有的URL并不是一个具体的网址,在存入时要进行判断,不是的要在前面加入**https://**不然无法进行访问和获取数据。)第三个是将列表中的数据,以列表名来分别存入小说名和地址,有的列表还需存入月票数与点击数。第四个是去获取刚刚存入的表名,用于向控制台输出。(因为我没写界面,所以就把控制台当做了界面进行操作。)
这个方法的完整代码。

def getmysql():
    url_first = "https://b.faloo.com/"
    soup = getSoup(url_first)
    getbook_list(soup)
    getNovels_list(soup)
    reslust=novelsql.sqlquery(0)
    return reslust
def getSoup(url):
    htmlText = getHtmlText(url)
    soup = bs4.BeautifulSoup(htmlText,'html.parser')
    return soup
def getHtmlText(url):
    r=requests.get(url,timeout=30)
    r.raise_for_status()
    r.encoding="gbk"
    return r.text
def getbook_list(soup):
    data =soup.find("div",{"class":"i_mm"})
    tablename=data.find("div",{"id":"tab2_box1_1"}).text
    novelsql.createtable(tablename,0)
    datas = data.find("div",{"id":"con_tab2_box_1"}).find("div",{"class":"c_list0"}).find_all("a")
    n=0
    for re in datas:
        if n == 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冲击的少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值