版权声明:原创作品,拥有版权 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°reefrom=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°reefrom=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()