孤荷凌寒自學python第七十九天開始寫Python的第一個爬蟲9並使用pydocx模塊將結果寫入word文檔

孤荷凌寒自學python第七十九天開始寫Python的第一個爬蟲9html

 

(完整學習過程屏幕記錄視頻地址在文末)python

 

今天在上一天的基礎上繼續完成對個人第一個代碼程序的書寫。web

到今天終於完成了對docx模塊針對word文檔的段落對象的操做的學習,並經過函數封裝,使得能夠輕鬆一點直接向word文檔中添加一個或多個段落文本而且設置段落的格式。sql

 

1、完成了批量添加word文檔段落的函數數據庫

```編程

def addPToDocx(f,strp,strfont='宋體',fontsize=14,fontcolor=RGBColor(0,0,0),stralign='左對齊',strlinespacingstyle='固定值',intlinespace=20,intlinespacebefore=0,intlinespaceafter=0,intfirstlineindent=100000,isShowMsg=False):網絡

    try:app

        lst=strp.split('\n')dom

        for i in lst:編程語言

            i.strip()

            try:

                stralign=stralign.lower()

                strlinespacingstyle=strlinespacingstyle.upper()

                strfont.decode('utf-8')

            except:

                pass

            #---先指定樣式------------------------

            styles = f.styles

            fls=time.time()

            strr='ghlhStyle%s' %fls  #自定義的樣式的名稱

            strr=strr.replace('.','')

            strr=strr+ ''.join(random.sample('zyxwvutsrqponmlkjihgfedcbaABCDEFGHIJKLMNOPQRST',5))

            s=styles.add_style(strr,WD_STYLE_TYPE.PARAGRAPH)

            s.font.name=strfont

            s.font.size=Pt(fontsize)

            s.font.color.rgb=fontcolor

            s._element.rPr.rFonts.set(qn('w:eastAsia'), strfont) #除中文外其它文字 使用的字體 ,備選項

            #----選擇正確的行距模式------------------------

            if strlinespacingstyle in '固定值,EXACTLY,固定行距,固定行間距':

                s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.EXACTLY #段落行距樣式爲固定值,必須指定行距值,不然就會變成 多倍行距 模式

            elif strlinespacingstyle in '多行行距,多倍行距,多行距,MULTIPLE':

                s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.MULTIPLE #多倍行距,此模式的具體行間距由文字字號大小決定,若是後面指定了行距值,此多倍行距設置會被忽略,變成固定值模式

            elif strlinespacingstyle in '單行行距,單倍行距,單行距,SINGLE':

                s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.SINGLE #段落行距樣式爲單倍行距 模式

            elif strlinespacingstyle in '1.5行距,1.5倍行距,一行半行距,一行半倍行距,一點五行距,一點五倍行距,ONE_POINT_FIVE':

                s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.ONE_POINT_FIVE #段落行距樣式爲 1.5倍行距 模式

            elif strlinespacingstyle in '雙行行距,雙倍行距,雙行距,兩行行距,兩倍行距,兩行距,二行行距,二倍行距,二行距,DOUBLE':

                s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.DOUBLE #段落行距樣式爲 雙倍行距 模式

            else:

                s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.AT_LEAST #段落行距樣式爲 最小行距 模式

 

            s.paragraph_format.line_spacing=Pt(intlinespace) #行距值

            s.paragraph_format.space_before=Pt(intlinespacebefore) #段前距

            s.paragraph_format.space_after=Pt(intlinespaceafter) #段後距

 

            if intfirstlineindent==100000:

                #--這個形參的默認值表示,首行自動縮進兩個字符寬度

                s.paragraph_format.first_line_indent=s.font.size * 2 #段落首行縮進量

            else:

                s.paragraph_format.first_line_indent=Pt(intfirstlineindent) #這時直接使用設置值

            #-------------------------------

            p=f.add_paragraph(i)

            p.style=s #--指定剛纔自定義的樣式

            #---接下來可調整對齊方式----

            if stralign in '靠左對齊,左邊對齊,左側,left':

                p.alignment=WD_ALIGN_PARAGRAPH.LEFT #水平左對齊

            elif stralign in '居中對齊,中間對齊,center':

                p.alignment=WD_ALIGN_PARAGRAPH.CENTER #水平居中對齊

            elif stralign in '靠右對齊,右邊對齊,右側,right':

                p.alignment=WD_ALIGN_PARAGRAPH.RIGHT #水平右對齊

            elif stralign in '分散對齊,兩邊對齊,兩側對齊,兩頭對齊,頭尾對齊,justify':

                p.alignment=WD_ALIGN_PARAGRAPH.JUSTIFY #水平分散對齊

            else:

                p.alignment=WD_ALIGN_PARAGRAPH.DISTRIBUTE

 

        return True

    except Exception as e:

        mwordErrString='嘗試未來自網頁的內容寫入word文檔正文時出錯:' + str(e) + '\n此函數由【孤荷凌寒】建立,QQ578652607'

        if isShowMsg==True:

           msgbox(mwordErrString)

        return False

    else:

        pass

    finally:

        pass

 

```

 

2、自定義文件【_mword.py】至此的文件內容以下:

 

 

```

#!/usr/bin/env python3

# -*- coding: utf-8 -*-

import string

import time

import random

 

from docx.enum.style import WD_STYLE_TYPE #全部樣式 (包括段落、文字、表格)的枚舉常量集

 

from docx.enum.text import WD_ALIGN_PARAGRAPH #對齊方式 的枚舉常量集,不過在vscode中顯示有錯,事實又可以執行

 

from docx.enum.text import WD_LINE_SPACING #行間距的單位枚舉常量集(包括:單倍行距,1.5倍行距,固定 值,最小值等)

 

from docx.oxml.ns import qn

from docx import *

 

from docx.shared import Inches #設置word中相關內容的計量單位爲:英寸

from docx.shared import Pt  #設置word中相關內容的計量單位爲:磅

 

from docx.shared import RGBColor #將三個數值生成色彩對象

 

import _mty

import _cl #經常使用常量模塊

import _mre

 

mwordErrString=''

 

def msgbox(info,titletext='孤荷凌寒的word模塊對話框QQ578652607',style=0,isShowErrMsg=False):

    return _mty.msgboxGhlh(info,titletext,style,isShowErrMsg)

 

def newDocX(strfilenm,isShowMsg=False):

    '''

    建立一個新的docx並保存在指定的路徑下成爲指定文件名的文件 。

    '''

    try:

        f=Document() #建立新文檔 對象

        f.save(strfilenm) #保存這個文件

        return f #f的類型是:<class 'docx.document.Document'>

    except Exception as e:

        mwordErrString='嘗試建立一個新的word文件時出錯:' + str(e) + '\n此函數由【孤荷凌寒】建立,QQ578652607'

        if isShowMsg==True:

           msgbox(mwordErrString)

        return None

    else:

        pass

    finally:

        pass

 

def addPToDocx(f,strp,strfont='宋體',fontsize=14,fontcolor=RGBColor(0,0,0),stralign='左對齊',strlinespacingstyle='固定值',intlinespace=20,intlinespacebefore=0,intlinespaceafter=0,intfirstlineindent=100000,isShowMsg=False):

    try:

        lst=strp.split('\n')

        for i in lst:

            i.strip()

            try:

                stralign=stralign.lower()

                strlinespacingstyle=strlinespacingstyle.upper()

                strfont.decode('utf-8')

            except:

                pass

            #---先指定樣式------------------------

            styles = f.styles

            fls=time.time()

            strr='ghlhStyle%s' %fls  #自定義的樣式的名稱

            strr=strr.replace('.','')

            strr=strr+ ''.join(random.sample('zyxwvutsrqponmlkjihgfedcbaABCDEFGHIJKLMNOPQRST',5))

            s=styles.add_style(strr,WD_STYLE_TYPE.PARAGRAPH)

            s.font.name=strfont

            s.font.size=Pt(fontsize)

            s.font.color.rgb=fontcolor

            s._element.rPr.rFonts.set(qn('w:eastAsia'), strfont) #除中文外其它文字 使用的字體 ,備選項

            #----選擇正確的行距模式------------------------

            if strlinespacingstyle in '固定值,EXACTLY,固定行距,固定行間距':

                s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.EXACTLY #段落行距樣式爲固定值,必須指定行距值,不然就會變成 多倍行距 模式

            elif strlinespacingstyle in '多行行距,多倍行距,多行距,MULTIPLE':

                s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.MULTIPLE #多倍行距,此模式的具體行間距由文字字號大小決定,若是後面指定了行距值,此多倍行距設置會被忽略,變成固定值模式

            elif strlinespacingstyle in '單行行距,單倍行距,單行距,SINGLE':

                s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.SINGLE #段落行距樣式爲單倍行距 模式

            elif strlinespacingstyle in '1.5行距,1.5倍行距,一行半行距,一行半倍行距,一點五行距,一點五倍行距,ONE_POINT_FIVE':

                s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.ONE_POINT_FIVE #段落行距樣式爲 1.5倍行距 模式

            elif strlinespacingstyle in '雙行行距,雙倍行距,雙行距,兩行行距,兩倍行距,兩行距,二行行距,二倍行距,二行距,DOUBLE':

                s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.DOUBLE #段落行距樣式爲 雙倍行距 模式

            else:

                s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.AT_LEAST #段落行距樣式爲 最小行距 模式

 

            s.paragraph_format.line_spacing=Pt(intlinespace) #行距值

            s.paragraph_format.space_before=Pt(intlinespacebefore) #段前距

            s.paragraph_format.space_after=Pt(intlinespaceafter) #段後距

 

            if intfirstlineindent==100000:

                #--這個形參的默認值表示,首行自動縮進兩個字符寬度

                s.paragraph_format.first_line_indent=s.font.size * 2 #段落首行縮進量

            else:

                s.paragraph_format.first_line_indent=Pt(intfirstlineindent) #這時直接使用設置值

            #-------------------------------

            p=f.add_paragraph(i)

            p.style=s #--指定剛纔自定義的樣式

            #---接下來可調整對齊方式----

            if stralign in '靠左對齊,左邊對齊,左側,left':

                p.alignment=WD_ALIGN_PARAGRAPH.LEFT #水平左對齊

            elif stralign in '居中對齊,中間對齊,center':

                p.alignment=WD_ALIGN_PARAGRAPH.CENTER #水平居中對齊

            elif stralign in '靠右對齊,右邊對齊,右側,right':

                p.alignment=WD_ALIGN_PARAGRAPH.RIGHT #水平右對齊

            elif stralign in '分散對齊,兩邊對齊,兩側對齊,兩頭對齊,頭尾對齊,justify':

                p.alignment=WD_ALIGN_PARAGRAPH.JUSTIFY #水平分散對齊

            else:

                p.alignment=WD_ALIGN_PARAGRAPH.DISTRIBUTE

 

        return True

    except Exception as e:

        mwordErrString='嘗試未來自網頁的內容寫入word文檔正文時出錯:' + str(e) + '\n此函數由【孤荷凌寒】建立,QQ578652607'

        if isShowMsg==True:

           msgbox(mwordErrString)

        return False

    else:

        pass

    finally:

        pass

 

```

 

3、測試用文件:

import requests

from bs4 import BeautifulSoup

import re

import datetime

import pymongo

 

from docx.shared import RGBColor #將三個數值生成色彩對象

 

import _mty

import _mf

import _mbs4

import _mmongo

import _mre

import _mdb

import _mword

 

intc=0

 

def msgbox(info,titletext='孤荷凌寒的DB模塊對話框QQ578652607',style=0,isShowErrMsg=False):

    return _mty.msgboxGhlh(info,titletext,style,isShowErrMsg)

 

def myfirst(s,h):

 

    c2=_mdb.conLocaldbGhlh(r'C:\ProgramData\SQLITE3\slone.s3db')

    lstNm=['id','title','newdate','source','content','adddate']

    lstType=['int','string','date','str','memo','date']

    lstLong=[0,255,0,255,0,0]

    lstNull=['not null','not null','not null','null','not null','null']

    lstPrimary=[True,False,False,False,False,False]

    lstAuto=[True,False,False,False,False,False]

 

    c3=_mdb.conLocaldbGhlh(r'C:\ProgramData\SQLITE3\new163.accdb')

 

    strt='news163'

    a=_mdb.newTablePlusGhlh('sqlite',c2,strt,lstNm,lstType,lstLong,lstNull,lstPrimary,lstAuto)

    msgbox(str(a))

    cursor=c2.cursor()

 

    b=_mdb.newTablePlusGhlh('acc',c3,strt,lstNm,lstType,lstLong,lstNull,lstPrimary,lstAuto)

    cursor3=c3.cursor()

 

    cursor.execute('select * from ' + strt + ';')

    data=cursor.fetchall()

    for i in data:

        msgbox(str(i))

 

    cursor3.execute('select * from ' + strt + ';')

    data=cursor3.fetchall()

    for i in data:

        msgbox(str(i))

 

    #return True

 

    #-------------------------

    r=requests.get(s,headers=h)

    #print(r.text) #r.text獲得的是頁面源html代碼

    _mf.writeAllTextToTxtFileGhlh('1.txt',r.text)

    bs=BeautifulSoup(r.text,features="lxml") #第二個參數指明瞭解析器,獲得的是一個beautifulsoup對象

    s=bs.prettify()

    _mf.writeAllTextToTxtFileGhlh('2.txt',str(s))

    rs=bs.select('.bigsize') #選擇指定style樣式表的html標籤元素

    for i in rs:

        ele=i.find_all('a') #每一個h5標籤下只有一個a標籤

        strls=ele[0].get('href')

        #msgbox(strls) #取出地址

        getcontentpage(strls,h,c2,cursor,c3,cursor3,strt)

        #break

    #---------------------

    #cursor.execute('select * from ' + strt + ';')

    #data=cursor.fetchall()

    #for i in data:

    #    msgbox(str(i))

 

    #cursor3.execute('select * from ' + strt + ';')

    #data=cursor3.fetchall()

    #for i in data:

    #    msgbox(str(i))

   

 

def getcontentpage(strurl,h,c2,cursor,c3,cursor3,strt):

    r=requests.get(strurl,headers=h)

    _mf.writeAllTextToTxtFileGhlh('3.txt',r.text)

    bs=BeautifulSoup(r.text,features="lxml") #第二個參數指明瞭解析器,獲得的是一個beautifulsoup對象

    s=bs.prettify()

    _mf.writeAllTextToTxtFileGhlh('4.txt',str(s))

    #---------------------------

    #eletemp=bs.find_all("#epContentLeft") #如今eletemp是一個rs集合對象

    #上一句是錯誤的,經過html標籤對象的id值來查找應當使用的方法是:select方法

    eletemp=bs.select('#epContentLeft') #list

    #msgbox(str(type(eletemp)))

    eletitleparent=eletemp[0] #bs.element.Tag

    #msgbox(str(type(eletitleparent)))

    eletitle=eletitleparent.h1

    elesource=eletitleparent.div #elesource這種對象如今被稱爲:bs.element.Tag對象,能夠被轉換爲列表,但不是列表

    #msgbox(str(elesource))

    strtitle=_mbs4.getAllTextGhlh(eletitle)

    strdate=list(elesource)[0]

    strdate=_mre.getDateAndTimeString(strdate)

    strsource=_mbs4.getAllTextGhlh(elesource.a)

    #msgbox(strtitle)

    #msgbox(strsource)

    #msgbox(strdate)

    #取正文

    elecontent=bs.select('#endText') #全部的正文內容都這個div中,elecotent是一個List?

    strcontent=_mbs4.getAllTextGhlh(elecontent)

    data={

        u'標題':strtitle,

        u'日期':strdate,

        u'來源':strsource,

        u'內容':strcontent,

        u'添加日期':datetime.datetime.now().__format__('%Y-%m-%d %H:%M:%S')

    }

    #msgbox(str(data))

 

    #寫入Mongodb數據庫

    c=_mmongo.conMongoDbGhlh('localhost')

    db=c.news163

    jh=db.first

    isok=_mmongo.addNewDataGhlh(jh,data)

    #msgbox(isok)

    #寫入sqlite3和ACCESS數據庫

    try:

        strsql="insert into " + strt + "(title,newdate,source,content,adddate) values('" + strtitle + "','" + strdate + "','" + strsource + "','" + strcontent + "','" + datetime.datetime.now().__format__('%Y-%m-%d %H:%M:%S') + "');"

        cursor.execute(strsql)

        cursor3.execute(strsql)

 

        c2.commit()

        c3.commit()

    except:

        msgbox('出錯了')

 

    #寫入word文檔

    try:

        global intc

        intc=intc+1

        strf='%03d' %intc

        strf=strf + '.docx'

        strf='I:\\MAKEAPP\\python\\Python365\\邊學習邊測試文件夾\\自學PYTHON部分\\0079第七十九天爬蟲實戰9\\docs\\' + strf

        f=_mword.newDocX(strf)

        _mword.addPToDocx(f,strtitle,'黑體',28,RGBColor(0,0,100),'l','1.5',0,0,20,0)

        #f.add_heading(strtitle,level=2) #這是添加標題段的方式 添加

        #f.add_heading(strsource,level=3)

        _mword.addPToDocx(f,strcontent)

 

        f.save(strf) #保存時必須有文件名做參數

        #f.close() #沒有這個命令

 

    except:

        msgbox('寫word出錯!')

        pass

 

strurl='http://tech.163.com/special/techscience/'

header={

'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',

'Accept-Encoding':'gzip, deflate',

'Accept-Language':'zh-CN,zh;q=0.9',

'Cache-Control':'max-age=0',

'Connection':'keep-alive',

'Cookie':'_ntes_nuid=4c64ad6c80e3504f05302ac133efb277; _ntes_nnid=eb7c24e0daf48e922e31dc81e431fde2,1536978956105; Province=023; City=023; NNSSPID=acab5be191004a2b81a3a6ee60f516dc; NTES_hp_textlink1=old; UM_distinctid=1683adcaeaf2f8-0e31bcdad8532c-3c604504-144000-1683adcaeb094d; vjuids=-7a5afdb26.1683adccded.0.d9d34439a4e48; vjlast=1547175776.1547175776.30; ne_analysis_trace_id=1547175775731; s_n_f_l_n3=7476c45eb02177f91547175775852; vinfo_n_f_l_n3=7476c45eb02177f9.1.0.1547175775852.0.1547176062972',

'Host':'tech.163.com',

'If-Modified-Since':'Fri, 11 Jan 2019 03:01:05 GMT',

'Referer':'http://tech.163.com/',

'Upgrade-Insecure-Requests':'1',

'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'

}

 

header2={

    'Host':'tech.163.com',

    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'

}

 

myfirst(strurl,header2)

 

4、今天的其它收穫小結:

(一)、在docx模塊操做word文檔時,添加自定義樣式的方法:

新的自定義樣式對象=word文檔對象.styles.add_style('新樣式命名',WD_STYLE_TYPE.PARAGRAPH)

 

而後將【新的自定義樣式對象】賦值給段落對象的.style屬性便可

word文檔段落對象的.style=新的自定義樣式對象

而不能在新增段落時,像使用word的內置樣式那樣在新增段落的第二個參數中傳入這個新的樣式對象的名稱。

這種方法只對word的內置樣式有效,自定義樣式若是也這樣作,將報錯。

 

(二)、隨機文本的生成方法

1.獲得一個字符串中的隨機字符

random.choice('字符串')

此方法將返回【字符串】中的一個隨機字符。

2.獲得一個字符串中的多個隨機字符,返回列表

random.sample('字符串',要返回的個數)

或者:

random.sample([字符串列表], 要返回的個數)

這兩個方法都將返回【要返回的個數】個來自於【字符串】中或【字符串列表】中的字符。

 

 

——————————

今天整理的學習筆記完成,最後例行說明下個人自學思路:

根據過去多年我自學各類編程語言的經歷,認爲只有真正體驗式,解決實際問題式的學習纔會有真正的效果,即讓學習實際發生。在2004年的時候我開始在一個鄉村小學自學電腦 並學習vb6編程語言,沒有學習同伴,也沒有高師在上,甚至電腦都是孤島(鄉村那時尚未網絡),有的只是一本舊書,在痛苦的自學摸索中,我找到適應本身零基礎的學習方法:首先是每讀書的一小節就做相應的手寫筆記,第二步就是上機測試每個筆記內容是否實現,其中會發現書中講的其實有出入或錯誤,第三步就是在上機測試以後,將筆記改成電子版,造成最終的修訂好的正確無誤的學習筆記 。

經過反覆嘗試錯誤,在那個沒有分享與交流的黑暗時期我摸黑學會了VB6,爾後接觸了其它語言,也曾聽過付費視頻課程,結果發現也許本身學歷果真過低,就算是零基礎的入門課程,其實也難以跟上進度,講師的教學多數出現對初學者的實際狀況並不瞭解的狀況,何況學習者的個體也存在差別呢?固然更可怕的是收費課程的價格每每是本身難以承受的。

因而個人全部編程學習都改成了自學,繼續本身的三步學習筆記法的學習之路。

固然自學的最大問題是會走那麼多的彎路,沒有導師直接輸入式的教學來得直接,好在網絡給咱們帶來無限搜索的機會,你們在網絡上的學習日誌帶給咱們共享交流的機會,而QQ羣等交流平臺、網絡社區的成立,咱們能夠一塊兒自學,互相批評交流,也能夠得到更有效,更自主的自學成果。

因而我以人生已過半的年齡,決定繼續個人編程自學之路,開始學習python,只但願與你們共同交流,一我的的獨行是可怕的,只有一羣人的共同前進纔是有但願的。

誠摯期待您的交流分享批評指點!歡迎聯繫我加入從零開始的自學聯盟。

這個時代互聯網成爲了一種基礎設施的存在,因而原本在孤獨學習之路上的咱們變得再也不孤獨,由於網絡就是一個新的客廳,咱們時刻均可以進行沙龍活動。

很是樂意能與你們一塊兒交流本身自學心得和發現,更但願你們可以對我學習過程當中的錯誤給予指點——是的,這樣我就能有許多免費的高師了——這也是分享時代,社區時代帶來的好福利,我相信你們會的,是吧!

 

根據徹底共享的精神,開源互助的理念,個人我的自學錄製過程是所有按4K高清視頻錄製的,從手寫筆記到驗證手寫筆記的上機操做過程全程錄製,但由於4K高清文件太大均超過5G以上,因此沒法上傳至網絡,若有須要可聯繫我QQ578652607對傳,樂意分享。上傳分享到百度網盤的只是壓縮後的720P的視頻。

 

個人學習過程錄像百度盤地址分享以下:(清晰度:1280x720)

連接:https://pan.baidu.com/s/1jCxMh5aswv8In09ny2IiaQ

提取碼:lg9r

 

Bilibili:

https://www.bilibili.com/video/av40974780/

 

喜馬拉雅語音筆記:

https://www.ximalaya.com/keji/19103006/155417466

相關文章
相關標籤/搜索