想学python爬虫?必会的正则表达,全在这了!(文末附赠教程分享)
字符串处理与网络爬虫
网络爬虫最重要的东西就是从页面中提取想要的数据,这就涉及对字符串的处理,因此,我将从字符串的处理开始介绍网络爬虫的入门。
字符串处理
字符串处理函数
函数名意义str.capitalize()返回字符串str的副本str.casefold()将字符串str中的大写字符转换为小写str.lower()同str.casefold(),只能转换英文字母str.upper()将字符串str中的小写转换为大写str.count(sub[, start[, end]])返回字符串str的子字符串sub出现的次数str.encode(encoding="utf-8", errors="strict")返回字符串str经过encoding编码后的字节码,errors指定了遇到编码错误时的处理方法str.find(sub[, start[, end]])返回字符串str的子字符串sub第一次出现的位置str.format(args, *kwargs)格式化字符串str.join(iterable)用str连接可迭代对象iterable返回连接后的结果str.strip([chars])去除str字符串两端的chars字符(默认去除" ",""," "),返回操作后的字符串str.lstrip([chars])同strip去除字符串最左边的字符str.rstrip([chars])同strip去除字符串最右边的字符str.replace(old, new[, count])将字符串str的子串old替换成新串new并返回操作后的字符串str.split(sep=None, maxsplit=-1)将字符串str按sep分隔符分割maxsplit次,并返回分割后的字符串数组
示例:
小编推荐大家可以加我的python官方部落群,点击链接加入群:python运维,里面有新手资料,不失为是一个学习的好地方,小编在这里邀请大家加入我的大家庭。欢迎你的到来。一起交流学习!共同进步!!
从结果我们知道,我们已经取得了href所指向的所有网址了。
匹配规则:
模式描述
^匹配字符串的开头
$匹配字符串的末尾。
.匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
[...]用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k'
[^...]不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
re*匹配0个或多个的表达式。
re+匹配1个或多个的表达式。
re?匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
re{ n}
re{ n}精确匹配n个前面表达式。
re{ n, m}匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
ab匹配a或b(re)G匹配括号内的表达式,也表示一个组
(?imx)正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。
(?-imx)正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。
(?: re)类似 (...), 但是不表示一个组
(?imx: re)在括号中使用i, m, 或 x 可选标志
(?-imx: re)在括号中不使用i, m, 或 x 可选标志
(?#...)注释.
(?= re)前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。
(?! re)前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功
(?> re)匹配的独立模式,省去回溯。
w匹配字母数字及下划线
W匹配非字母数字及下划线
s匹配任意空白字符,等价于 [].
S匹配任意非空字符
d匹配任意数字,等价于 [0-9].
D匹配任意非数字
A匹配字符串开始
Z匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。c
z匹配字符串结束
G匹配最后匹配完成的位置。
匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
B匹配非单词边界。'erB' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
, , 等.匹配一个换行符。匹配一个制表符。等
...9匹配第n个分组的内容。
匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。
示例:编码与解码
通过第三方库chardet可以判断字节码的编码方式,如下:
示例:chardet
可以看到,utf8字节码被判断成utf-8编码的自信度还是很高的,99%,而gbk字节码被判定成了TIS-620,其自信度43%显然太小不足信。
网络爬虫
示例:
从源码中提取信息
re
前面介绍字符串处理时已经介绍过,它将整个html文档当作字符串处理,提取出我们想要的数据。
BeautifulSoup4
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间。----官方介绍
我们接下来会讲到常用的方法,当然讲到的都是重要的,其他的方法能办到的我们都可以办到。
示例:
打开G:/test.csv文件,如下:
保存到数据库
由于Python原生支持sqlite3数据库,并且此数据库小巧功能又十分强大,因此我们选用sqlite3数据库作为演示,其他数据库使用方式类似,不同的在于依赖库不同、SQL语法不同。
示例:
用工具软件打开G:/test.db数据库:
爬虫从这里开始
用chrome打开上面的网址,画面如下:
我们需要从页面中提取电影名、评分、描述,以及获取下一页链接并循环爬取直到最后一页。
流程图如下:
第一步:(引包)
from urllib import requestfrom chardet import detectfrom bs4 import BeautifulSoupimport re
第二步:(获取网页源码生成soup对象)
def getSoup(url): """获取源码""" with request.urlopen(url) as fp: byt = fp.read() det = detect(byt) return BeautifulSoup(byt.decode(det['encoding']),'lxml')
第四步:(解析数据)
首先我们找到包含电影的大标签如下:
取出右边部分如下:
是一个ol标签,并且class属性值为grid_view。
找到每个电影单独的大标签如下:
是一个li标签,也就是ol的子标签。
打开li标签,我们就看到了需要抓取的数据。
因此我们子需要抓取li标签下的子标签一些满足要求的span标签里的数据即可。
def getData(soup): """获取数据""" data = [] ol = soup.find('ol', attrs={'class': 'grid_view'}) for li in ol.findAll('li'): tep = [] titles = [] for span in li.findAll('span'): if span.has_attr('class'): if span.attrs['class'][0] == 'title': titles.append(span.string.strip()) elif span.attrs['class'][0] == 'rating_num': tep.append(span.string.strip()) elif span.attrs['class'][0] == 'inq': tep.append(span.string.strip()) tep.insert(0, titles) data.append(tep) return data
第五步:(获取下一页链接)
def nextUrl(soup): """获取下一页链接后缀""" a = soup.find('a', text=re.compile("^后页")) if a: return a.attrs['href'] else: return None
第六步:(组织代码结构开始爬行)
安装:
Scrapy及其依赖包下载:
- Scrapy‑1.4.0‑py2.py3‑none‑any.whl
- Twisted‑17.5.0‑cp34‑cp34m‑win32.whl
- lxml-3.7.3-cp34-cp34m-win_amd64.whl
笔者环境为py3.4,因此安装包会有py34或py3字样,py2.x同理
当然你还需要vc++10.0
首先是Twisted包与lxml包的安装:
pip install Twisted-17.5.0-cp34-cp34m-win_amd64.whl
pip install lxml-3.7.3-cp34-cp34m-win_amd64.whl
Scrapy的安装:
pip install Scrapy-1.4.0-py2.py3-none-any.whl
注: 顺序不要错,不然有莫名其妙的错误
豆瓣TOP250Scrapy版:
为了初始化方便,我们新建如下文件:(初始化.py)
import ospname = input('项目名:')os.system("scrapy startproject " + pname)os.chdir(pname)wname = input('爬虫名:')sit = input('网址:')os.system('scrapy genspider ' + wname + ' ' + sit)runc = """from scrapy.crawler import CrawlerProcessfrom scrapy.utils.project import get_project_settingsfrom %s.spiders.%s import %s# 获取settings.py模块的设置settings = get_project_settings()process = CrawlerProcess(settings=settings)# 可以添加多个spider# process.crawl(Spider1)# process.crawl(Spider2)process.crawl(%s)# 启动爬虫,会阻塞,直到爬取完成process.start()""" % (pname, wname, wname[0].upper() + wname[1:] + 'Spider', wname[0].upper() + wname[1:] + 'Spider')with open('main.py', 'w', encoding = 'utf-8') as f: f.write(runc)input('end')
运行上述文件初始化代码模板:
项目名:douban
爬虫名:top250
网址:movie.douban.com/top250
执行完毕即可生成项目结构,相关文件描述如下:
文件夹文件描述doubanmain.py程序运行总入口doubanscrapy.cfg项目的配置文件douban/douban__init__.py初始化douban/doubanitems.py抓取内容描述douban/doubanmiddlewares.py中间件douban/doubanpipelines.py管道,数据的清洗与存储douban/doubansettings.py配置文件douban/douban/spiders__init__.py初始文件douban/douban/spiderstop250.py爬虫文件
编写items.py,确定需要爬取的项目:
from scrapy import Item, Fieldclass DoubanItem(Item): name = Field() fen = Field() words = Field()
编写爬虫文件top250.py:
port csvclass DoubanPipeline(object): def __init__(self): self.fp = open('TOP250.csv','w', encoding = 'utf-8') self.wrt = csv.DictWriter(self.fp, ['name','fen','words']) self.wrt.writeheader() def __del__(self): self.fp.close() def process_item(self, item, spider): self.wrt.writerow(item) return item
在这里我们将爬到的数据存入了TOP250.csv文件中。
然后配置settings.py文件:
BOT_NAME = 'douban'SPIDER_MODULES = ['douban.spiders']NEWSPIDER_MODULE = 'douban.spiders'# 该死的豆瓣必须加这个USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'ROBOTSTXT_OBEY = FalseITEM_PIPELINES = { 'douban.pipelines.DoubanPipeline': 300}
到此为止,我们就可以运行主程序main.py了。
最后,想学习Python的小伙伴们!
请关注+私信回复:“学习”就可以拿到一份我为大家准备的Python学习资料!
pytyhon学习资料
python学习资料