今天我们要做的事是爬取影评,首先捋下思路:
1)引入相关库
2)获取网页
3)解析网页
4)处理数据
5)存储数据
import requests
from requests.exceptions import RequestException
import re
import json
import urllib.request
对于这些库是干嘛的,出门右转找度娘!在这里只简单介绍两个库requests和re
requests:用来获取网页。
中文参考文档 http://docs.python-requests.org/zh_CN/latest/index.html
re:通过正则表达式来匹配我们需要的信息,从而解析网页得到数据。
> 常用的正则表达式元字符
元字符 含义
. 匹配除换行符以外的任意一个字符
[] 匹配[]中列举的字符
^ 匹配行首
$ 匹配行尾
? 重复匹配0次或1次
* 重复匹配0次或更多次
+ 重复匹配1次或更多次
{n,} 重复n次或更多次
{n,m} 重复n~m次
[a-z] a-z之间的任意字符
[abc] a/b/c中的任意一个字符
{n} 重复n次
\d 匹配数字,即0-9
\D 匹配非数字,即匹配不是数字的字符
\s 匹配空白符,也就是 空格\tab
\S 匹配非空白符,\s取反
\w 匹陪单词字符, a-z, A-Z, 0-9,
\W 匹配非单词字符, \w取反
\\( 匹配括号,转义即可
常用的字符匹配函数
1.Match函数进行字符匹配和搜索
形式:re.match(‘正则表达式’,’待匹配字符串’)
功能:从字符串的起始位置匹配,如果不是起始位置匹配成功,match()就返回none
2. search函数进行字符匹配和搜索
形式:re.match(‘正则表达式’,’待匹配字符串’)
功能: 扫描整个字符串并返回第一个成功的匹配。
> match只匹配字符串的开始,如字符串开始不符合正则表达式,则匹配失败,函数返回None;
> search匹配整个字符串,直到找到一个匹配。
3. findall函数进行字符匹配和搜索
形式: re.findall(‘正则表达式’,’待匹配字符串’)
功能:以列表形式返回全部能匹配正则表达式的子串;
4. 字符串替换
形式:re.sub(‘正则表达式’,’替换字符串’,’待替换的字符串’)
功能:用于替换字符串中的匹配项;
5. 字符串分隔
形式: re.split(‘正则表达式’,’待匹配字符串’)
功能:按照能够匹配的子串将字符串分割后返回列表;
举个例子
1)匹配账号是否合法:^[A-Za-z][A-Za-z0-9]{4,15}$
账号以字母开头,允许字母、数字和下划线,包括5-16个字符;
2)匹配国内电话号码:\d{3}-\d{8}|\d{4}-\d{7}
3)匹配QQ号码,QQ从1000开始: [1-9][0-9]{4,}
4)匹配身份证号,身份证为15位或18位: \d{15}|\d{18}
5)匹配电子邮件:
邮箱名称部分为: [a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+){0,4}
域名部分: [a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+
连起来 ^[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+){0,4}@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+){0,4}$
这一步我们要做的是通过URL统一资源定位符(即网址)获取该网页的HTML超文本标记语言。
def get_one_page(url):
try:
# 添加头部信息
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
' (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36'
}
response = requests.get(url, headers=headers)
# 进行状态码判断,是否正确读取到网页
if response.status_code == 200:
return response.text
return None
except RequestException:
return None
> 这里,get_one_page(url)函数返回的一个html(即网页源代码)
得到了网页,下一步当然是将网页中的内容读取出来啦。
def analyze_one_page(pattern, html):
# 解析网页,获取数据,pattern为正则表达式序列
data = re.findall(pattern, html)
return data
> 这里,analyze_one_page(pattern,html)函数返回data,data中存储着从网页中爬取到的信息
> 用pattern这个正则表达式去匹配html这个网页源代码,符合正则表达式的数据就存放到列表data中
有了读取网页的函数,接着,我们就来爬取豆瓣上的电影吧!
def get_all_movies():
# url_1 是豆瓣电影最新排行榜网址
url_1 = 'https://movie.douban.com/chart'
# pattern_1 用于爬取排行榜上电影信息【网址,名字,海报】
pattern_1 = re.compile('.*?' +
'.*?
(.*?)', re.S)
html_1 = get_one_page(url_1)
data_1 = analyze_one_page(pattern_1, html_1)
return data_1
> compile:编译正则表达式模式,返回一个对象的模式。(可以把那些常用的正则表达式编译成正则表达式对象,以提高效率。)
我们为了方便调用这些数据,理所当然要给他们起上名字。之前数据存储在列表data中,这里,只需将列表转化为字典即可做到起名的效果。
题外话:如果是处理 像考试成绩这类数字很多的信息,可能会用到numpy,pandas库
def analyze_data_1():
# 对数据进行初步的处理
data_1 = get_all_movies()
for data1 in data_1:
yield {
'网址': data1[0],
'名字': data1[1],
'海报': data1[2],
'评分': data1[3]
}
return data_1
存储数据,这里就涉及到了文件的读写,我们先来了解一下。
5.1文件打开
open(file, mode=‘r’, buffering=None, encoding=None, errors=None,newline=None, closefd=True)
参数说明:
•参数file是被打开的文件名称,如果文件file不存在,open()将创建名为name的文件,然后再打开该文件。
•参数mode是指文件的打开模式。文件的打开模式请参照以下内容。
•参数buffering是设置缓存模式。0表示不缓存,1表示缓存;如果大于1则表示缓冲区的大小,以字节为单位。
•参数encoding是设置文件的字符编码格式。
•open()函数会返回一个file对象,file 对象可以对文件进行各种操作
<\n>
<\n>
参数mode的基本取值
Character Meaning
‘r’ open for reading (default)
‘w’ open for writing, truncating the file first
‘a’ open for writing, appending to the end of the file if it exists
‘b’ binary mode
‘t’ text mode (default)
‘+’ open a disk file for updating (reading and writing)
‘U’ universal newline mode (for backwards compatibility; should not be used in new code)
r、w、a为打开文件的基本模式,对应着只读、只写、追加模式;
b、t、+、U这四个字符,与以上的文件打开模式组合使用,二进制模式,文本模式,读写模式、通用换行符,根据实际情况组合使用、
<\n>
<\n>
常见的mode取值组合
r或rt 默认模式,文本模式读
rb 二进制文件
w或wt 文本模式写,打开前文件存储被清空
wb 二进制写,文件存储同样被清空
a 追加模式,只能写在文件末尾
a+ 可读写模式,写只能写在文件末尾
w+ 可读写,与a+的区别是要清空文件内容
r+ 可读写,与a+的区别是可以写到文件任何位置
5.2 文件的读取
文件的读取有多种方法,可以使用readline()、readlines()、或read()函数读取文件。
1.按行读取方式readline()
2.多行读取方式readlines()
3.一次性读取方式read()
5.3文件的删除
文件的删除需要使用os模块和os.path模块,os模块提供了系统的环境、文件、目录等操作系统的函数。
<\n>手动换行,emmmm
<\n>
对于文件来说比较常用的os模块的函数如下:
•os.access(path,mode)#按照mode指定的权限进行访问
•os.chmod(path,mode)#改变文件的访问权限,mode用UNIX的权限符号表示
•os.open(filename,flag[,mode=0777])#按照mode指定的权限打开文件。默认情况下,给所有用户读、写、执行的权限
•os.remove(path)#删除path指定的文件
•os.rename(old,new)#重命名文件或目录,old表示原文件或目录,new表示新文件或目录
•os.stat(path)#返回path指定文件的所有属性
•os.fstat(path)#返回打开文件的所有属性
•os.startfile(filepath[,operation])#启动关联程序打开文件。例如,打开一个html文件,将启动IE浏览器
•os.tmpfile()#创建一个临时文件,文件创建在操作系统的临时目录中
注意:os模块的open()函数与内建的open()函数的用法不同。
<\n>
os.path模块常用的函数如下:
•os.path.abspath(path)#返回path所在的绝对路径
•os.path.dirpath(path)#返回目录的路径
•os.path.exists(path)#判断文件是否存在
•os.path.getatime(filename)#返回文件的最后访问时间
•os.path.getctime(filename)#返回文件的创建时间
•os.path.getmtime(filename)#返回文件最后的修改时间
•os.path.getsize(filename)#返回文件的大小
<\n>
os.path判断函数
•os.path.isabs(s)#测试路径是否是绝对路径
•os.path.isdir(path)#判断path指定的是否是目录
•os.path.isfile(path)#判断path指定的是否是文件
•os.path.split§#对路径进行分割,并以列表的方式返回
•os.path.splitext§#从路径中分割文件的扩展名
•os.path.splitdrive§#从路径中分割驱动器的名称
•os.walk(top,func,arg)#遍历目录树
以上皆为引用,参考
有梦就要去实现他:http://www.cnblogs.com/ymjyqsx/p/6554817.html
Python文件处理:https://www.jb51.net/article/80204.htm
读取数据的三种方法:
法1:无脑操作,打开>>>读取>>>关闭
f = open('/Users/michael/test.txt', 'r')
f.read()
f.close()
法2:由于文件读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。所以,为了保证无论是否出错都能正确地关闭文件,我们可以使用try … finally来实现:
try:
f = open('/path/to/file', 'r')
print(f.read())
finally:
if f:
f.close()
法3:但是每次都这么写实在太麻烦,所以,Python引入了with语句来自动帮我们调用close()方法:
with open('/path/to/file', 'r') as f:
print(f.read())
这和前面的try … finally是一样的,但是代码更佳简洁,并且不必调用f.close()方法。
下面,进入正题,将我们爬取的数据存进文件。这里写了两个函数,一个是将数据写进文件,一个是将图片保存至文件夹。相关函数,大家可以去搜一下,这里就不多介绍了,本渣渣灰对文件的读写也很迷。。。
# 将数据写入文件
def write_to_file(content, filename):
# 以读写的方式存储
with open(filename, 'a+', encoding='utf-8') as f:
f.write(json.dumps(content, ensure_ascii=False) + '\n')
f.close()
# 将图片保存至文件夹
def write_to_picture(imgUrl, name, path):
# imgUrl 图片的链接,name 图片的命名,path 图片存储的路径
new_path = path + '/' + name + '.jpg'
urllib.request.urlretrieve(imgUrl, new_path)
write_to_picture()函数里面提到了路径,关于路径,嗯…
1、相对路径: 相对路径就是相对于当前文件的路径。网页中一般表示路径使用这个方法。
相对路径使用的几个特殊符号:
“./”:代表目前所在的目录。
“…/”:代表上一层目录。
以"/"开头:代表根目录。
2、绝对路径: 绝对路径就是你的主页上的文件或目录在硬盘上真正的路径。比如,你的data文件是存放在 c:/users/ doucment下的,那么c:/users/doucment就是doucment目录的绝对路径
可参考,搜狗百科:
https://baike.sogou.com/v67630690.htm?fromTitle=相对路径
https://baike.sogou.com/v7534903.htm?fromTitle=绝对路径
3、虚拟路径:比如“/img/bg.jpg”,“img”前有一个“/”字符。这个“/”代表的是虚拟目录的根目录. 假设把“E:\data”设为虚拟目录,那么“/img/bg.jpg”的真实路径为“E:\data\img \bg.jpg”;如果把“E:\data\picture”设为虚拟目录,那么“/img/bg.jpg”的真实路径为“E:\data\picture\img\bg.jpg”
。。。划重点。。。。
大家是否会迷惑一个问题?有时候路径用 '\‘表示 ,有时候用’/'表示
路径的表示方法:
记住三点:
main()函数代码就不外放了,搬砖的工作,我已经做完了,大家快去爬取自己想爬取的网页吧!
后期持续更新…
嘻嘻嘻,第一次写,有错误请大家指出!!!