九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

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

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ú)有。對其知識(shí)點(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è)能夠匹配括號(hào)內(nèi)正則a(?=\d)a1最后的結(jié)果得到a(?!…)順序否定環(huán)視,表示所在位置右側(cè)不能匹配括號(hào)內(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á)式中的空白和#號(hào)的注釋

對于一個(gè)特殊字符在正則表達(dá)式中是不能正常識(shí)別的,如果接觸過其他語言我們就這到有一個(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é)果:

匹配規(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é)果

以上可以看出:

(1) () 匹配括號(hào)內(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é)果

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

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

結(jié)果

以上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é)果:

轉(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é)果:

其中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é)果:

可以看出兩個(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é)果:

    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é)果:

    我們可以看出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)#這里就用到了我們上述提到的一些知識(shí)點(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é)果:


    以上看到并非按順序排列因?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é)果:

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

    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)知。上面寫的知識(shí)點(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://maoyan.com/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)])
    本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
    打開APP,閱讀全文并永久保存 查看更多類似文章
    猜你喜歡
    類似文章
    Python爬蟲從入門到精通(解析庫re的使用:正則表達(dá)式)
    爬蟲的解析方式三:正則表達(dá)式
    Perl 正則表達(dá)式 | 菜鳥教程
    python中的正則表達(dá)式
    Python超詳細(xì)的正則表達(dá)式
    學(xué)Python正則表達(dá)式,這一篇就夠了
    更多類似文章 >>
    生活服務(wù)
    熱點(diǎn)新聞
    分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
    綁定賬號(hào)成功
    后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
    如果VIP功能使用有故障,
    可點(diǎn)擊這里聯(lián)系客服!

    聯(lián)系客服