久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

想要玩爬蟲,!正則表達(dá)式是你的必修課程!這篇足以你玩轉(zhuǎn)爬蟲了,!

 精神360 2018-10-13

python 3.x 爬蟲基礎(chǔ)

python 3.x 爬蟲基礎(chǔ)---http headers詳解

python 3.x 爬蟲基礎(chǔ)---Urllib詳解

python 3.x 爬蟲基礎(chǔ)---Requersts,BeautifulSoup4(bs4)

python 3.x 爬蟲基礎(chǔ)---正則表達(dá)式

前言

正則表達(dá)式是對字符串的一種邏輯公式,,用事先定義好的一些特定字符、及這些特定字符的組合,,組成一個(gè)“規(guī)則的字符串”,,此字符串用來表示對字符串的一種“過濾”邏輯。正在在很多開發(fā)語言中都存在,,而非python獨(dú)有,。對其知識點(diǎn)進(jìn)行總結(jié)后,會(huì)寫一個(gè)demo,。

私信小編01 02 03 04 即可獲取數(shù)十套PDF哦,!以及大量的學(xué)習(xí)資料!

1.正則表達(dá)式

python是自1.5開始引進(jìn)re模塊進(jìn)行處理正則的,。我先把正則的匹配規(guī)則總結(jié)一下,,再總結(jié)re模塊相應(yīng)的方法。

1.1匹配規(guī)則

語法解釋表達(dá)式成功匹配對象一般字符匹配自身相對應(yīng)的字符abcabc.匹配除換行符(\n)以外的任意字符a.cabc\轉(zhuǎn)義字符,,可以改變原字符的意思a.ca.c\d匹配數(shù)字:0~9\dabc1abc\w匹配單詞字符,a~z;A~Z;0~9\w\w\woX2\s匹配空格字符(\t,\n,\r,\f,\v)a\sca c\D匹配非數(shù)字字符\Dabcaabc\W匹配非單詞字符a\Wca c\S匹配非空格字符\S\Sc1bc[]字符集,,對應(yīng)位置上可以是字符集里的任意字符a[def]caec[^]對字符集當(dāng)中的內(nèi)容進(jìn)行取反a[^def]ca2c[a-z]指定一個(gè)范圍字符集a[A-Z]caBc*允許前一個(gè)字符可以出現(xiàn)0次或者無限次a*baaab或b+前一個(gè)字符至少出現(xiàn)1次a+baaab或ab?前一個(gè)字符只能出現(xiàn)一次或者不出現(xiàn)a?bab或b{m}允許前一個(gè)字符只能出現(xiàn)m次a{3}baaab{m,n}允許前一個(gè)字符至少出現(xiàn)m次,最多出現(xiàn)n次(如果不寫n,則代表至少出現(xiàn)m次)a{3,5}b和a{3,}aaaab和aaaaaab^匹配字符串的開始,,多行內(nèi)容時(shí)匹配每一行的開始^abcabc$匹配字符串的結(jié)尾,,多行內(nèi)容時(shí)匹配每一行的結(jié)尾abc&abc\A匹配字符串開始位置,忽略多行模式\Aabcabc\Z匹配字符串結(jié)束位置,,忽略多行模式abc\Zabc\b匹配位于單詞開始或結(jié)束位置的空字符串hello \bworldhello world\B匹配不位于單詞開始或結(jié)束位置的空字符串he\Bllohello|表示左右表達(dá)式任意滿足一種即可abc|cbaabc或cba(…)將被括起來的表達(dá)式作為一個(gè)分組,,可以使用索引單獨(dú)取出(abc)dabcd(?P…)為該分組起一個(gè)名字,可以用索引或名字去除該分組(?Pabc)dabcd\number引用索引為number中的內(nèi)容(abc)d\1abcdabc(?P=name)引用該name分組中的內(nèi)容(?Pabc)d(?P=id)abcdabc(?:…)分組的不捕獲模式,,計(jì)算索引時(shí)會(huì)跳過這個(gè)分組(?:a)b(c)d\1abcdc(?iLmsux)分組中可以設(shè)置模式,,iLmsux之中的每個(gè)字符代表一個(gè)模式(?i)abcAbc(?#…)注釋,#后面的內(nèi)容會(huì)被忽略ab(?#注釋)123ab123(?=…)順序肯定環(huán)視,,表示所在位置右側(cè)能夠匹配括號內(nèi)正則a(?=\d)a1最后的結(jié)果得到a(?!…)順序否定環(huán)視,,表示所在位置右側(cè)不能匹配括號內(nèi)正則a(?!\w)a c最后的結(jié)果得到a(?<><>

上面表格中(?iLmsux)這里的”i”, “L”, “m”, “s”, “u”, “x”,它們不匹配任何字串,,而對應(yīng)re模塊中(re.S|re.S):

I:re.I# 忽略大小寫L:re.L# 字符集本地化,為了支持多語言版本的字符集使用環(huán)境U :re.U# 使用\w,\W,\b,\B這些元字符時(shí)將按照UNICODE定義的屬性M:re.M # 多行模式,改變 ^ 和 $ 的行為S:re.S # '.' 的匹配不受限制,包括換行符X:re.X # 冗余模式,可以忽略正則表達(dá)式中的空白和#號的注釋

對于一個(gè)特殊字符在正則表達(dá)式中是不能正常識別的,,如果接觸過其他語言我們就這到有一個(gè)叫做轉(zhuǎn)移字符的東西的存在,在特殊字符前加用反斜杠接口,。比如\n換行\(zhòng)\為反斜杠,,在這不再累述。下面來介紹一下re這個(gè)模塊,。

1.2.re模塊

此模塊主要方法如下

re.match()#嘗試從字符串的起始位置匹配一個(gè)模式(pattern),,如果不是起始位置匹配成功的話,match()就返回Nonere.search()#函數(shù)會(huì)在字符串內(nèi)查找模式匹配,只要找到第一個(gè)匹配然后返回,,如果字符串沒有匹配,,則返回None。re.findall()#遍歷匹配,,可以獲取字符串中所有匹配的字符串,,返回一個(gè)列表。re.compile()#編譯正則表達(dá)式模式,,返回一個(gè)對象的模式,。(可以把那些常用的正則表達(dá)式編譯成正則表達(dá)式對象,這樣可以提高一點(diǎn)效率,。)re.sub()#使用re替換string中每一個(gè)匹配的子串后返回替換后的字符串,。re.subn()#返回替換次數(shù)re.split()#按照能夠匹配的子串將string分割后返回列表。

1.2.1.re.match()

方法: re.match(pattern, string, flags=0) # pattern:正則表達(dá)式(或者正則表達(dá)式對象)string:要匹配的字符串flags:修飾符

先看一個(gè)最簡單的用法

import recontent ='Hello 123 4567 wangyanling REDome'print(len(content))result = re.match('^Hello\s\d\d\d\s\d{4}\s\w{10}.*Dome$', content)print(result)print(result.group())print(result.span())

結(jié)果:

想要玩爬蟲,!正則表達(dá)式是你的必修課程,!這篇足以你玩轉(zhuǎn)爬蟲了,!

匹配規(guī)則就不在累述,,以上需要注意的是

(1) .group() 表示的是返回正則匹配的結(jié)果

(2) .span() 表示返回正則匹配的范圍

使用:

以上我們已經(jīng)知道re.matcha()的具體方法,那么接下我來看一下具體使用,,對此我們要理解以下幾種匹配的感念,。

1.泛匹配(.*):匹配所有字符

import recontent ='Hello 123 4567 wangyanling REDome'result = re.match('^Hello.*Dome$', content)print(result)print(result.group())print(result.span())

它的結(jié)果是和上面的輸出結(jié)果完全一樣的。

2.目標(biāo)匹配(()):將需要的字符匹配出來

import recontent ='Hello 123 4567 wangyanling REDome'result = re.match('^Hello\s\d\d(\d)\s\d{4}\s\w{10}.*Dome$', content)print(result)print(result.group(1))import recontent ='Hello 123 4567 wangyanling REDome'result = re.match('^Hello\s(\d+)\s\d{4}\s\w{10}.*Dome$', content)print(result)print(result.group(1))

結(jié)果

想要玩爬蟲,!正則表達(dá)式是你的必修課程!這篇足以你玩轉(zhuǎn)爬蟲了,!

以上可以看出:

(1) () 匹配括號內(nèi)的表達(dá)式,也表示一個(gè)組

(2) + 匹配1個(gè)或多個(gè)的表達(dá)式

*匹配0個(gè)或多個(gè)的表達(dá)式

(3) .group(1) —輸出第一個(gè)帶有()的目標(biāo)

3.貪婪匹配(.*()):匹配盡可能少的的結(jié)果

import recontent ='Hello 123 4567 wangyanling REDome'result = re.match('^H.*(\d+).*Dome$', content)print(result)print(result.group(1))

結(jié)果

想要玩爬蟲,!正則表達(dá)式是你的必修課程,!這篇足以你玩轉(zhuǎn)爬蟲了,!

4.貪婪匹配(.*?()):匹配盡可能多的結(jié)果

import recontent ='Hello 123 4567 wangyanling REDome'result = re.match('^H.*?(\d+).*?Dome$', content)print(result)print(result.group(1))

結(jié)果

想要玩爬蟲!正則表達(dá)式是你的必修課程,!這篇足以你玩轉(zhuǎn)爬蟲了,!

以上3,4兩個(gè)匹配方式請盡量采用非貪婪匹配

5.其他

換行:

import recontent ='''Hello 123 4567 wangyanling REDome'''result = re.match('^H.*?(\d+).*?Dome$', content,re.S)#re.Sprint(result.group(1))result = re.match('^H.*?(\d+).*?Dome$', content)print(result.group(1))

結(jié)果:

想要玩爬蟲,!正則表達(dá)式是你的必修課程,!這篇足以你玩轉(zhuǎn)爬蟲了,!

轉(zhuǎn)義字符:

import recontent = 'price is $5.00'result = re.match('price is $5.00', content)print(result)result = re.match('price is \$5\.00', content)print(result)

結(jié)果:

想要玩爬蟲,!正則表達(dá)式是你的必修課程,!這篇足以你玩轉(zhuǎn)爬蟲了!

其中re.I使匹配對大小不敏感,re.S匹配包括換行符在內(nèi)的所有字符,\進(jìn)行處理轉(zhuǎn)義字符。匹配規(guī)則中有詳細(xì)介紹,。

1.2.2.re.search()

方法:

re.search(pattern, string, flags=0)#pattern:正則表達(dá)式(或者正則表達(dá)式對象)string:要匹配的字符串flags:修飾符 #re.match()和re.search()用法類似唯一的區(qū)別在于re.match()從字符串頭開始匹配,若頭匹配不成功,則返回None

對比一下與match()

import recontent ='Hello 123 4567 wangyanling REDome'result = re.match('(\d+)\s\d{4}\s\w{10}.*Dome$', content)print(result)#從開頭開始查找,,不能匹配返回Noneresult = re.search('(\d+)\s\d{4}\s\w{10}.*Dome$', content)print(result)print(result.group())

結(jié)果:

想要玩爬蟲,!正則表達(dá)式是你的必修課程,!這篇足以你玩轉(zhuǎn)爬蟲了,!

可以看出兩個(gè)使用基本一致,,search從頭開始匹配,,如果匹配不到就返回none.

1.2.3.re.findall()

方法: re.finditer(pattern, string, flags=0) # pattern:正則表達(dá)式(或者正則表達(dá)式對象)string:要匹配的字符串flags:修飾符

與re.search()類似區(qū)別在于re.findall()搜索string,,返回一個(gè)順序訪問每一個(gè)匹配結(jié)果(Match對象)的迭代器,。找到 RE 匹配的所有子串,并把它們作為一個(gè)迭代器返回,。

import rehtml = '''
  • 吶喊
  • 廢都
  • 平凡世界
  • 謝謝支持
    '''regex_4='(.*?)'results=re.findall(regex_4,html,re.S)print(results)for result in results: print(result)

    結(jié)果:

    想要玩爬蟲,!正則表達(dá)式是你的必修課程,!這篇足以你玩轉(zhuǎn)爬蟲了!

    1.2.4.re.compile()

    編譯正則表達(dá)式模式,,返回一個(gè)對象的模式。

    方法: re.compile(pattern,flags=0) # pattern:正則表達(dá)式(或者正則表達(dá)式對象);flags:修飾符

    看一個(gè)demo

    import recontent ='Hello 123 4567 wangyanling REDome wangyanling 那小子很帥'rr = re.compile(r'\w*wang\w*')result =rr.findall(content)print(result)

    結(jié)果:

    想要玩爬蟲!正則表達(dá)式是你的必修課程,!這篇足以你玩轉(zhuǎn)爬蟲了!

    我們可以看出compile 我們可以把它理解為封裝了一個(gè)公用的正則,,類似于方法,,然后功用,。

    1.2.5.其他

    re.sub 替換字符

    方法: re.sub(pattern, repl, string, count=0, flags=0) # pattern:正則表達(dá)式(或者正則表達(dá)式對象)repl:替換的字符串string:要匹配的字符串count:要替換的個(gè)數(shù)flags:修飾符

    re.subn 替換次數(shù)

    方法: re.subn(pattern, repl, string, count=0, flags=0) # pattern:正則表達(dá)式(或者正則表達(dá)式對象)repl:替換的字符串string:要匹配的字符串count:要替換的個(gè)數(shù)flags:修飾符

    re.split()分隔字符

    方法

    re.split(pattern, string,[maxsplit])#正則表達(dá)式(或者正則表達(dá)式對象)string:要匹配的字符串,;maxsplit:用于指定最大分割次數(shù),不指定將全部分割

    2.案例:爬取貓眼信息,,寫入txt,csv,下載圖片

    2.1.獲取單頁面信息

    def get_one_page(html): pattern= re.compile('
    .*?board-index.*?>(\d+).*?data-src='(.*?)'.*?name'>(.*?).*?star'>(.*?)

    .*?releasetime' + '.*?>(.*?)

    .*?score.*?integer'>(.*?).*?>(.*?).*?
    ',re.S)#這里就用到了我們上述提到的一些知識點(diǎn),非貪婪匹配,,對象匹配,修飾符 items = re.findall(pattern,html) for item in items: yield { 'rank' :item[0], 'img': item[1], 'title':item[2], 'actor':item[3].strip()[3:] if len(item[3])>3 else '', 'time' :item[4].strip()[5:] if len(item[4])>5 else '', 'score':item[5] + item[6] }

    對于上面的信息我們可以看出是存到一個(gè)對象中那么接下來我們應(yīng)該把它們存到文件當(dāng)中去,。

    2.2.保存文件

    我寫了兩種方式保存到txt和csv這些在python都有涉及,,不懂得可以去翻看一下。

    2.2.1.保存到txt

    def write_txtfile(content): with open('Maoyan.txt','a',encoding='utf-8') as f: #要引入json,利用json.dumps()方法將字典序列化,存入中文要把ensure_ascii編碼方式關(guān)掉 f.write(json.dumps(content,ensure_ascii=False) + '\n') f.close()

    結(jié)果:

    想要玩爬蟲,!正則表達(dá)式是你的必修課程,!這篇足以你玩轉(zhuǎn)爬蟲了!


    以上看到并非按順序排列因?yàn)槲矣玫氖嵌嗑€程,。

    2.2.2.保存到csv

    def write_csvRows(content,fieldnames): '''寫入csv文件內(nèi)容''' with open('Maoyao.csv','a',encoding='gb18030',newline='') as f: #將字段名傳給Dictwriter來初始化一個(gè)字典寫入對象 writer = csv.DictWriter(f,fieldnames=fieldnames) #調(diào)用writeheader方法寫入字段名 writer.writerows(content) f.close()

    結(jié)果:

    想要玩爬蟲,!正則表達(dá)式是你的必修課程!這篇足以你玩轉(zhuǎn)爬蟲了,!

    那么還有一部就是我們要把圖片下載下來,。

    2.2.3.下載圖片

    def download_img(title,url): r=requests.get(url) with open(title+'.jpg','wb') as f: f.write(r.content)

    2.3.整體代碼

    這里面又到了多線程在這不在敘述后面會(huì)有相關(guān)介紹。這個(gè)demo僅做一案例,,主要是對正則能有個(gè)認(rèn)知,。上面寫的知識點(diǎn)有不足的地方望大家多多指教,。

    #抓取貓眼電影TOP100榜from multiprocessing import Poolfrom requests.exceptions import RequestExceptionimport requestsimport jsonimport timeimport csvimport redef get_one_page(url): '''獲取單頁源碼''' try: headers = { 'User-Agent':'Mozilla/5.0(WindowsNT6.3;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/68.0.3440.106Safari/537.36' } res = requests.get(url, headers=headers) # 判斷響應(yīng)是否成功,若成功打印響應(yīng)內(nèi)容,否則返回None if res.status_code == 200: return res.text return None except RequestException: return Nonedef parse_one_page(html): '''解析單頁源碼''' pattern = re.compile('
    .*?board-index.*?>(\d+).*?data-src='(.*?)'.*?name'>(.*?).*?star'>(.*?)

    .*?releasetime' + '.*?>(.*?)

    .*?score.*?integer'>(.*?).*?>(.*?).*?
    ',re.S) items = re.findall(pattern,html) #采用遍歷的方式提取信息 for item in items: yield { 'rank' :item[0], 'img': item[1], 'title':item[2], 'actor':item[3].strip()[3:] if len(item[3])>3 else '', #判斷是否大于3個(gè)字符 'time' :item[4].strip()[5:] if len(item[4])>5 else '', 'score':item[5] + item[6] }def write_txtfile(content): with open('Maoyan.txt','a',encoding='utf-8') as f: #要引入json,利用json.dumps()方法將字典序列化,存入中文要把ensure_ascii編碼方式關(guān)掉 f.write(json.dumps(content,ensure_ascii=False) + '\n') f.close()def write_csvRows(content,fieldnames): '''寫入csv文件內(nèi)容''' with open('Maoyao.csv','a',encoding='gb18030',newline='') as f: #將字段名傳給Dictwriter來初始化一個(gè)字典寫入對象 writer = csv.DictWriter(f,fieldnames=fieldnames) #調(diào)用writeheader方法寫入字段名 #writer.writeheader() ###這里寫入字段的話會(huì)造成在抓取多個(gè)時(shí)重復(fù). writer.writerows(content) f.close()def download_img(title,url): r=requests.get(url) with open(title+'.jpg','wb') as f: f.write(r.content)def main(offset): fieldnames = ['rank','img', 'title', 'actor', 'time', 'score'] url = 'http:///board/4?offset={0}'.format(offset) html = get_one_page(url) rows = [] for item in parse_one_page(html): #download_img(item['rank']+item['title'],item['img']) write_txtfile(item) rows.append(item) write_csvRows(rows,fieldnames)if __name__ == '__main__': pool = Pool() #map方法會(huì)把每個(gè)元素當(dāng)做函數(shù)的參數(shù),創(chuàng)建一個(gè)個(gè)進(jìn)程,在進(jìn)程池中運(yùn)行. pool.map(main,[i*10 for i in range(10)])

      本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào),。
      轉(zhuǎn)藏 分享 獻(xiàn)花(0

      0條評論

      發(fā)表

      請遵守用戶 評論公約

      類似文章 更多