1. 程式人生 > >Python爬蟲(正則表示式)

Python爬蟲(正則表示式)

Python爬蟲(正則表示式)

最近接觸爬蟲比較多,下面我來展示一個剛爬取的成果,使用正則表示式的方法,希望對剛開始接觸爬蟲的小夥伴有所幫助,同時希望大佬們給予點評和指導

接下來,步入正題,使用正則表示式爬取資料是一種原始且有效的方法,正則表示式的作用即字元匹配,匹配出你想得到的資料。

對於正則表示式做一下簡單整理:

  • re模組:不同的語言均有使用正則表示式的方法,但各不相同。Python是通過re模組來實現的。
>>>import re
>>> re.search(r'python','java\python\C\C++\php')
<_sre.SRE_Match object; span=(5, 11), match='python'>

search()方法用於在字串中搜索正則表示式模式第一次出現的位置,這裡找到了,匹配的位置是(5,11)
注意兩點:
1、第一個引數是正則表示式
2、找到後返回範圍是以下標0開始的;如果找不到,它就返回None.

  • 萬用字元:*和?就是大家熟知的萬用字元,用它表示任何字元。正則表示式也有萬用字元,在這裡用一個點號(.)來表示,它可以匹配除了換行符之外的任意字元:
>>> re.search(r'.','java\python\C\C++\php')
<_sre.SRE_Match object; span=(0, 1), match='j'>
#數量詞
#*匹配0次或者無限多次
#+匹配1次或者無限多次
#?匹配0次或者1次->可以轉化成非貪婪
import re

a='pytho0python1pythonn2'

r=re.findall('python*',a)
m=re.findall('python+',a)
p=re.findall('python{1,2}?',a)

#貪婪與非貪婪
print(r)
print(m)
print(p)

輸出結果分別為:

['pytho', 'python', 'pythonn']
['python', 'pythonn']
['python', 'python']
  • 反斜槓:消除特殊字元的特殊功能,即用字元的形式顯示特殊字元。
>>> re.search(r'\.','java\python\C\C++\php.')
<_sre.SRE_Match object; span=(21, 22), match='.'>

下面爬取https://www.51job.com/

  • 搜尋欄中輸入python,地址為北京、上海、深圳、廣州
  • 使用正則表示式,輸出待搜尋網頁上的部分資訊,如下圖:
    在這裡插入圖片描述

一、要求輸出工作地點、薪資和釋出時間

(1、工作地點只輸出北京、上海、廣州、深圳
2、薪資要求最低、最高工資及萬\錢、年\月分別輸出

import re
from urllib import request
#地址
url='https://search.51job.com/list/010000%252C020000%252C030200%252C040000,000000,0000,00,9,99,python,2,1.html?lang=c&stype=&postchannel=0000&workyear=99&cotype=99&degreefrom=99&jobterm=99&companysize=99&providesalary=99&lonlat=0%2C0&radius=-1&ord_field=0&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare='

r=request.urlopen(Spider.url)
htmls=r.read()
htmls=str(htmls,encoding='gbk')
#定位標籤div
s=re.findall('<span class="t3">(北京|上海|深圳|廣州).*</span>\s*<span class="t4">(\d+\.*\d*)-(\d+\.*\d*)(千|萬)/(年|月)</span>\s*<span class="t5">([\s\S]*?)</span>',htmls)
#s=re.findall('<div class="el">([\s\S]*?)</div>',htmls)
#s=re.findall('<span class="t3">(北京|上海|深圳|廣州).*</span>\s*<span class="t4">(\d+\.*\d*)-(\d+\.*\d*)(千|萬)/(年|月)</span>',htmls)

for i in range(0,len(s)):
    for j in range(0,6):
        print(s[i][j],end='       ')
    print()      

二、要求輸出工作地點、薪資和釋出時間(完整輸出)

import re
from urllib import request
#斷點除錯
class Spider():
    url='https://search.51job.com/list/010000%252C020000%252C030200%252C040000,000000,0000,00,9,99,python,2,1.html?lang=c&stype=&postchannel=0000&workyear=99&cotype=99&degreefrom=99&jobterm=99&companysize=99&providesalary=99&lonlat=0%2C0&radius=-1&ord_field=0&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare='
    #定位標籤div
   
    root_pattern='<div class="el">([\s\S]*?)</div>'
    addr_pattern='<span class="t3">([\s\S]*?)</span>'
    salary_pattern='<span class="t4">([\s\S]*?)</span>'
    date_pattern='<span class="t5">([\s\S]*?)</span>'
    '''
    root_pattern='<div class="el">([\s\S]*?)</div>'
    addr_pattern='<span class="t3">(北京|上海|深圳|廣州).*</span>'
    salary_pattern='<span class="t4">(\d+\.*\d*)-(\d+\.*\d*)(千|萬)/(年|月)</span>'
    date_pattern='<span class="t5">([\s\S]*?)</span>'
    '''
    def __fetch_content(self):
        r=request.urlopen(Spider.url)
        htmls=r.read()
        htmls=str(htmls,encoding='gbk')
        return htmls

    #分析文字    
    def __analysis(self,htmls):
        root_html=re.findall(Spider.root_pattern,htmls)
        anchors=[]
        for html in root_html:
            addr=re.findall(Spider.addr_pattern,html)
            salary=re.findall(Spider.salary_pattern,html)
            '''
            for i in range(0,len(salary)):
               for j in range(0,4):
                   w=salary[i][j]
                   print(w,end='         ')
               h=salary[i]
               print(h)
               print()
            #print(salary)
            '''
            date=re.findall(Spider.date_pattern,html)
            anchor={'addr':addr,'salary':salary,'date':date}
            anchors.append(anchor)        
        #print(root_html[0])
        #print(len(root_html[0]))     
        return anchors

    #定義字典
    def __refine(self,anchors):
        
        l=lambda anchor:{'addr':anchor['addr'][0].strip(),
                        'salary':anchor['salary'][0],
                        'date':anchor['date'][0] 
                        }
        
        return map(l,anchors)

    #編寫排序函式
    def __sort(self,anchors):
        anchors=sorted(anchors,key=self.__sort_seed)
        return anchors

    def __sort_seed(self,anchor):
        return anchor['addr']
    
    #編寫函式,使得得到的字典有序的打印出來
    def __show(self,anchors):
        
        for anchor in anchors:
            print(anchor['addr']+'        '+anchor['salary']+'        '+anchor['date'])

        '''
        for anchor in anchors:
            print(anchor['addr']+'       '+anchor['date'])

        '''
    #入口方法
    def go(self):
       htmls= self.__fetch_content()
       anchors=self.__analysis(htmls)
       anchors=list(self.__refine(anchors))
       anchors=self.__sort(anchors)
       #print(anchors)
       self.__show(anchors)

spider=Spider()
spider.go()