python用正則爬取豆瓣電影排行榜,連老司機都不知道的奧祕

python用正則爬取豆瓣電影排行榜,連老司機都不知道的奧秘

使用了tkinter做了簡單頁面

首先分析要爬取的url, 發現每個頁面有25條內容, 總共有十頁, 第一頁的URL為https://movie.douban.com/top250?start=0&filter=

第二頁的url為https://movie.douban.com/top250?start=25&filter=

第三頁第四頁也是類似的URL, 只是修改了start後面的數字, 第一頁是0, 往後每增加25, 所以url的格式為https://movie.douban.com/top250?start=+{ID}

然後分析如何爬取內容:

首先爬取標題:

查看源代碼後, 發現標題是放在這樣的代碼:

  12345

發現電影的名稱一般都放在

電影名稱1

這樣的標記對中, 所以根據這個可以寫出正則表達式:

(.*?)1

不過在後面的測試中發現這樣寫的話, 每個電影名稱能獲取兩個信息

python用正則爬取豆瓣電影排行榜,連老司機都不知道的奧秘

 肖申克的救贖  / The Shawshank Redemption12

顯然第二條信息不是我們想要的, 經過對比發現第二條信息中都會有兩個空格的代碼, 所以把&給過濾掉就可以了:

(.[^&]*?)1

接下來爬取評分, 評分一般放在這樣的代碼中:

9.6 716019人評價
123456

這個正則就很好寫了:

"v:average">(.*?)1

這樣就ok啦, 這個程序還是非常簡單的, 上源代碼:

# -*- coding: utf-8 -*-from Tkinter import *from ScrolledText import ScrolledTextimport requests, re, threadingdef replite(ID): varl.set('正在獲取第%d頁內容' % (ID / 25 + 1)) html = 'https://movie.douban.com/top250?start=' + str(ID) response = requests.get(html).text # response = unicode(response, 'GBK').encode('UTF-8') response = response.encode('utf-8 ') # print response # reg = r'(.*?).*?"v:average">(.*?)' regTitle = r'(.[^&]*?)' regStars = r'.*?"v:average">(.*?)' regTitle = re.compile(regTitle) regStars = re.compile(regStars) titles = re.findall(regTitle, response) stars = re.findall(regStars, response) info = list(zip(titles, stars)) return infodef write(): varl.set('開始爬取內容') ID = 0 nums = 1 while ID < 250: res = replite(ID) ID += 25 for each in res: text.insert(END, 'No.%d\t%-30s%s分\n' % (nums, each[0], each[1])) nums += 1 varl.set('獲取內容成功')def start(): t1 = threading.Thread(target=write) t1.start()def save(): content = text.get("0.0", "end").encode('GBK') textfile = open(u'E:\\豆瓣電影排行250.txt', 'w') textfile.write(content) textfile.close()root = Tk()root.title('豆瓣電影top250')root.geometry('820x500+400+200')text = ScrolledText(root, font=('楷體', 15), width=80, height=20)text.grid()frame = Frame(root)frame.grid()# 啟動爬蟲功能startButton = Button(frame, text='開始', font=('楷體', 18), command=start)startButton.grid()startButton.pack(side=LEFT)# 保存爬取信息saveButton = Button(frame, text='保存文件', font=('楷體', 18), command=save)saveButton.grid()saveButton.pack(side=LEFT)# 退出程序exitButton = Button(frame, text='退出', font=('楷體', 18), command=frame.quit)exitButton.grid()exitButton.pack(side=LEFT)varl = StringVar()info_label = Label(root, fg='red', textvariable=varl)info_label.grid()varl.set('準備中....')root.mainloop() 

python用正則爬取豆瓣電影排行榜,連老司機都不知道的奧秘

下面給大家分享python正則詳解:

正則表達式是一個很強大的字符串處理工具,幾乎任何關於字符串的操作都可以使用正則表達式來完成,作為一個爬蟲工作者,每天和字符串打交道,正則表達式更是不可或缺的技能,正則表達式的在不同的語言中使用方式可能不一樣,不過只要學會了任意一門語言的正則表達式用法,其他語言中大部分也只是換了個函數的名稱而已,本質都是一樣的。下面,我來介紹一下python中的正則表達式是怎麼使用的。

  首先,python中的正則表達式大致分為以下幾部分:

    1. 元字符

    2. 模式

    3. 函數

    4. re 內置對象用法

    5. 分組用法

    6. 環視用法

  所有關於正則表達式的操作都使用 python 標準庫中的 re 模塊。

python用正則爬取豆瓣電影排行榜,連老司機都不知道的奧秘

一、元字符 (參見 python 模塊 re 文檔)

    • . 匹配任意字符(不包括換行符)

    • ^ 匹配開始位置,多行模式下匹配每一行的開始

    • $ 匹配結束位置,多行模式下匹配每一行的結束

    • * 匹配前一個元字符0到多次

    • + 匹配前一個元字符1到多次

    • ? 匹配前一個元字符0到1次

    • {m,n} 匹配前一個元字符m到n次

    • \\ 轉義字符,跟在其後的字符將失去作為特殊元字符的含義,例如\\.只能匹配.,不能再匹配任意字符

    • [] 字符集,一個字符的集合,可匹配其中任意一個字符

    • | 邏輯表達式 或 ,比如 a|b 代表可匹配 a 或者 b

    • (...) 分組,默認為捕獲,即被分組的內容可以被單獨取出,默認每個分組有個索引,從 1 開始,按照"("的順序決定索引值

    • (?iLmsux) 分組中可以設置模式,iLmsux之中的每個字符代表一個模式,用法參見 模式 I

    • (?:...) 分組的不捕獲模式,計算索引時會跳過這個分組

    • (?P...) 分組的命名模式,取此分組中的內容時可以使用索引也可以使用name

    • (?P=name) 分組的引用模式,可在同一個正則表達式用引用前面命名過的正則

    • (?#...) 註釋,不影響正則表達式其它部分,用法參見 模式 I

    • (?=...) 順序肯定環視,表示所在位置右側能夠匹配括號內正則

    • (?!...) 順序否定環視,表示所在位置右側不能匹配括號內正則

    • (?<=...) 逆序肯定環視,表示所在位置左側能夠匹配括號內正則

    • (?

    • (?(id/name)yes|no) 若前面指定id或name的分區匹配成功則執行yes處的正則,否則執行no處的正則

    • \number 匹配和前面索引為number的分組捕獲到的內容一樣的字符串

    • \A 匹配字符串開始位置,忽略多行模式

    • \Z 匹配字符串結束位置,忽略多行模式

    • \b 匹配位於單詞開始或結束位置的空字符串

    • \B 匹配不位於單詞開始或結束位置的空字符串

    • \d 匹配一個數字, 相當於 [0-9]

    • \D 匹配非數字,相當於 [^0-9]

    • \s 匹配任意空白字符, 相當於 [ \t\n\r\f\v]

    • \S 匹配非空白字符,相當於 [^ \t\n\r\f\v]

    • \w 匹配數字、字母、下劃線中任意一個字符, 相當於 [a-zA-Z0-9_]

    • \W 匹配非數字、字母、下劃線中的任意字符,相當於 [^a-zA-Z0-9_]

二、模式

    • I IGNORECASE, 忽略大小寫的匹配模式, 樣例如下

      python用正則爬取豆瓣電影排行榜,連老司機都不知道的奧秘

      s = 'hello World!'regex = re.compile("hello world!", re.I)print regex.match(s).group()#output> 'Hello World!'#在正則表達式中指定模式以及註釋regex = re.compile("(?#註釋)(?i)hello world!")print regex.match(s).group()#output> 'Hello World!'

      python用正則爬取豆瓣電影排行榜,連老司機都不知道的奧秘

    • L LOCALE, 字符集本地化。這個功能是為了支持多語言版本的字符集使用環境的,比如在轉義符\w,在英文環境下,它代表[a-zA-Z0-9_],即所以英文字符和數字。如果在一個法語環境下使用,缺省設置下,不能匹配"é" 或 "ç"。加上這L選項和就可以匹配了。不過這個對於中文環境似乎沒有什麼用,它仍然不能匹配中文字符。

    • M MULTILINE,多行模式, 改變 ^ 和 $ 的行為

      python用正則爬取豆瓣電影排行榜,連老司機都不知道的奧秘

      s = '''first linesecond linethird line'''# ^regex_start = re.compile("^\w+")print regex_start.findall(s)# output> ['first']regex_start_m = re.compile("^\w+", re.M)print regex_start_m.findall(s)# output> ['first', 'second', 'third']#$regex_end = re.compile("\w+$")print regex_end.findall(s)# output> ['line']regex_end_m = re.compile("\w+$", re.M)print regex_end_m.findall(s)# output> ['line', 'line', 'line']

      python用正則爬取豆瓣電影排行榜,連老司機都不知道的奧秘

    • S  DOTALL,此模式下 '.' 的匹配不受限制,可匹配任何字符,包括換行符

      python用正則爬取豆瓣電影排行榜,連老司機都不知道的奧秘

      s = '''first linesecond linethird line'''#regex = re.compile(".+")print regex.findall(s)# output> ['first line', 'second line', 'third line']# re.Sregex_dotall = re.compile(".+", re.S)print regex_dotall.findall(s)# output> ['first line\nsecond line\nthird line']

      python用正則爬取豆瓣電影排行榜,連老司機都不知道的奧秘

    • X VERBOSE,冗餘模式, 此模式忽略正則表達式中的空白和#號的註釋,例如寫一個匹配郵箱的正則表達式

      email_regex = re.compile("[\w+\.]+@[a-zA-Z\d]+\.(com|cn)")email_regex = re.compile("""[\w+\.]+ # 匹配@符前的部分 @ # @符 [a-zA-Z\d]+ # 郵箱類別 \.(com|cn) # 郵箱後綴 """, re.X)
    • U UNICODE,使用 \w, \W, \b, \B 這些元字符時將按照 UNICODE 定義的屬性.

正則表達式的模式是可以同時使用多個的,在 python 裡面使用按位或運算符 | 同時添加多個模式

如 re.compile('', re.I|re.M|re.S)

每個模式在 re 模塊中其實就是不同的數字

python用正則爬取豆瓣電影排行榜,連老司機都不知道的奧秘

print re.I# output> 2print re.L# output> 4print re.M# output> 8print re.S# output> 16print re.X# output> 64print re.U# output> 32

四、re 內置對象用法

    • SRE_Pattern 這個對象是一個編譯後的正則表達式,編譯後不僅能夠複用和提升效率,同時也能夠獲得一些其他的關於正則表達式的信息

屬性:

  • flags 編譯時指定的模式

  • groupindex 以正則表達式中有別名的組的別名為鍵、以該組對應的編號為值的字典,沒有別名的組不包含在內。

  • groups 正則表達式中分組的數量

python用正則爬取豆瓣電影排行榜,連老司機都不知道的奧秘

  • pattern 編譯時用的正則表達式

  • s = 'Hello, Mr.Gumby : 2016/10/26'p = re.compile('''(?: # 構造一個不捕獲分組 用於使用 | (?P\w+\.\w+) # 匹配 Mr.Gumby | # 或 (?P\s+\.\w+) # 一個匹配不到的命名分組 ) .*? # 匹配 : (\d+) # 匹配 2016 ''', re.X)

python用正則爬取豆瓣電影排行榜,連老司機都不知道的奧秘

好了,今天的知識就分享到這裡,歡迎關注愛編程的南風,私信關鍵詞:學習資料,獲取更多學習資源,如果文章對你有有幫助,請收藏關注,在今後與你分享更多學習python的文章。同時歡迎在下面評論區留言如何學習python。


分享到:


相關文章: