Python爬虫(正则表达式)

版权声明:原创作品,拥有版权 https://blog.csdn.net/G_AOFAN/article/details/83864918

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()


猜你喜欢

转载自blog.csdn.net/G_AOFAN/article/details/83864918