python爬虫第一个案例

1、一念永恒

首先给出原文链接:https://jackcui.blog.csdn.net/article/details/78123502,

由于是几年前的教程,所以里面的代码在我这里不能直接用,需要修改,也是踩了不少的坑。

一念永恒小说:https://www.bqkan.com/1_1094/

image-20210109190820145

A read the eternal.py

环境:python 3.8 pycharm 2019.2.5

# @Time : 2021/1/9 16:26 
# @Author : 六花
# @File : A read the eternal.py
# @Software: PyCharm

import requests
import bs4
import sys

class downloader (object):
#   定义初始参数
    def __init__(self):
        self.server="http://www.biqukan.com/"
        self.target ="http://www.biqukan.com/1_1094/"
        self.names = []  # 存放章节名
        self.urls = []  # 存放章节链接
        self.nums = 0  # 章节数

#   获取下载链接
    def get_downloader_url(self):
        req=requests.get(url=self.target)
        req.encoding=req.apparent_encoding
        html=req.text
        print(html)
        div_bf =bs4.BeautifulSoup(html,'lxml')
        listmain=div_bf.find_all('div', class_ = 'listmain')
        a_bf=bs4.BeautifulSoup(str(listmain[0]),'lxml')
        a=a_bf.find_all('a')
        self.nums=len(a[12:])
        print(a[12:])
        for each in a[12:]:
            self.names.append(each.string)
            self.urls.append(self.server+each.get('href'))

#   获取章节内容
    def get_contents(self,target):
        req=requests.get(url=target)
        req.encoding = req.apparent_encoding
        html=req.text
        div_bf = bs4.BeautifulSoup(html, 'lxml')
        div = div_bf.find_all('div', class_='showtxt')
        texts = div[0].text.replace(' ', '\n').replace('\xa0'*8, '\n')
        return texts

#   把爬到的内容写入文件
    def writer(self, name, path, text):
        write_flag  = True
        with open(path,'a',encoding='utf-8') as f:
            f.write(name +'\n')
            f.writelines(text)
            f.write('\n\n')

if __name__ == '__main__':
    dl=downloader()
    dl.get_downloader_url()
    print("开始下载")
    print(dl.urls)
    for i in range(dl.nums):
        dl.writer(dl.names[i], '一念永恒.txt', dl.get_contents(dl.urls[i]))
        sys.stdout.write("  已下载:%.3f%%" % float(i / dl.nums) + '\r')
        sys.stdout.flush()
    print('《一年永恒》下载完成')

其中,最头疼的就是乱码问题,也是百度了很久才知道,

这是爬的效果图,并没有出现乱码情况:

image-20210109191123176

出现中文乱码的时候,在返回req的时候, 给req.encoding = req.apparent_encoding

req.encoding:从HTTP header中猜测的响应内容的编码方式。是从http中的header中的charset字段中提取的编码方式,若header中没有charset字段则默认为ISO-8859-1编码模式,则无法解析中文,这是乱码的原因

req.apparent_encoding:从内容中分析出的响应内容编码方式。会从网页的内容中分析网页编码的方式,所以apparent_encoding比encoding更加准确。当网页出现乱码时可以把apparent_encoding的编码格式赋值给encoding。

2、豆瓣TOP250

学习使用了sqlite,xlwt等,最重要的是正则表达式的书写,本身的爬取并不难,但是有各种要求之后,爬取就变得很麻烦。

根据blibli视频手敲代码,出现bug时百度修改。

spider.py文件,引入了anncode

# @Time : 2021/1/7 10:10
# @Author : 六花
# @File : spider.py
# @Software: PyCharm

import bs4  #进行网页解析
import re   #正则表达式,进行文字匹配
import urllib.request
import urllib.error
 #制定url,获取网页数据
import xlwt  #进行excel操作
import sqlite3  #进行sqlite数据库操作


def main():
    baseurl = "https://movie.douban.com/top250?start="
#     1.爬取网页
    datalist = getData(baseurl)
    savepath = ".\\豆瓣电影TOP250.xls"
    dbpath="movie.db"
#     2.逐个解析数据
#     3.保存数据
    saveData(savepath,datalist)
    saveData2(dbpath,datalist)


#影片详情链接的规则
findLink = re.compile(r'a class="" href="(.*?)">') #生成正则表达式对象,表示规则
findImgs = re.compile(r'<img.*src="(.*?)"',re.S)
findTitle = re.compile(r'<span class="title">(.*?)</span>')
findRating = re.compile(r'<span class="rating_num" property="v:average">(.*?)</span>')
findJudge = re.compile(r'<span>(\d*)人评价</span>')
findInq = re.compile(r'<span class="inq">(.*)</span>')
findBd = re.compile(r'<p class="">(.*?)</p>',re.S)
# 爬取网页
def getData(baseurl):
    datalist = []
    for i in range(0,10): #调用10次,每次25个数据,一共250个数据。
        url = baseurl + str(i*25)
        html = askURL(url)
        # print(html)
        # 2.逐个解析数据,因为爬到一个网页就得解析一次
        soup=bs4.BeautifulSoup(html,"html.parser")
        for item in soup.find_all('div',class_="item"):#查找符合要求的字符串,形成列表
            data=[] #保存一部电影的所有信息
            item=str(item)
            #获取影片详情链接
            link=re.findall(findLink,item)[0] #使用正则表达式
            data.append(link)
            imgs=re.findall(findImgs, item)[0]
            data.append(imgs)
            title = re.findall(findTitle, item)
            if(len(title)==2):
                ctitle=title[0]
                ctitle=re.sub(r'\xa0'or '/',"",title[0])
                data.append(ctitle)
                otitle=title[1].replace("","")
                otitle = re.sub(r'\xa0'or'/', "", title[1])
                data.append(otitle)
            else:
                data.append(title[0])
                data.append(" ")
            rating = re.findall(findRating,item)[0]
            data.append(rating)
            judge = re.findall(findJudge, item)[0]
            data.append(judge)
            inq = re.findall(findInq, item)
            if(len(inq)!=0):
                inq=inq[0]
                data.append(inq)
            else:
                data.append('')
            bd=re.findall(findBd, item)[0]
            bd=re.sub('<br(\s+)?/>(\s+)?'," ",bd)
            bd=re.sub('\xa0','',bd)
            bd=re.sub("/"," ",bd)
            data.append(bd.strip()) #去掉空格
            datalist.append(data)
    return datalist



# 得到指定的一个URL网页内容
def askURL(url):
    headr = {
        #模拟浏览器头部向信息,向豆瓣发送消息
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36"
    } #用户代理:表示告诉豆瓣服务器,我们是什么类型的机器,浏览器,我们可以接收什么水平的文件
    request = urllib.request.Request(url, headers=headr)
    try:
        response = urllib.request.urlopen(request)
        html=response.read().decode("utf-8")
        # print(html)
    except urllib.error.URLError as e:
        if hasattr(e,"code"): #检查该对象是否有某个属性
            print(e.code)
        if hasattr(e,"reason"):
            print(e.reason)
    return html


# 保存数据到Excel
def saveData(savepath,datalist):
    print("save...............")
    book = xlwt.Workbook(encoding="utf-8",style_compression=0)  # 创建wookbook对象
    sheet = book.add_sheet("豆瓣电影top250")  # 创建工作表
    col=("电影详情链接","图片链接","影片中文名字","影片外文名","评分","评价数","概况","相关信息")
    for i in range(0,8):
        sheet.write(0,i,col[i]) #写列名字
    for i in range(0,250):
        print("第%d条"%i)
        data=datalist[i]
        for j in range(0,8):
            sheet.write(i+1,j,data[j])
    book.save(savepath)

# 保存数据到数据库
def saveData2(dbpath,datalist):
    init_db(dbpath)
    conn = sqlite3.connect(dbpath)
    cur = conn.cursor()
    for data in datalist:
        for index in range(len(data)):
            if index==4 or index==5:
                continue
            data[index]='"'+str(data[index])+'"'
        sql='''
            insert into movie250(info_link,pic_link,cname,ename,score,rated,instroduction,info)
            values (%s) ''' % ",".join(data)
        cur.execute(sql)
        conn.commit()
    cur.close()
    conn.close()


def init_db(dbpath):
    sql='''
            create table if not exists movie250
            (
            id integer  primary key autoincrement,
            info_link text,
            pic_link text,
            cname varchar,
            ename varchar,
            score numeric,
            rated numeric,
            instroduction text,
            info text
            )
    '''
    conn=sqlite3.connect(dbpath)
    cursor = conn.cursor()
    cursor.execute(sql)
    conn.commit()
    conn.close()


if __name__ == "__main__":
    main()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值