爬虫前期准备工作网络爬虫往往难度不在于代码的实现过程,而是在准备环节上。在进行爬取之前必须对网页的结构进行分析,对页面的排版也要有充分的了解。以本实验有分析豆瓣电影网站为例,介绍在预处理阶段的一般步骤:
1. 打开豆瓣电影Top250网页,(https://movie.douban.com/top250)。网页都有唯一的URL(统一资源定位符,也就是网址)进行定位,所以必须获取项目所需的基本url。所有的页面包括了250条电影数据,分为10页,每页25条,可以从每页的URL中发现其规律:start的数值=(页数-1)×25。
2. 按键盘上的开发者工具(F12),查看浏览器访问的headers信息,分析headers等信息,便于后期模仿用户对页面的浏览。查看得到的具体内容如图1.2所示。另外,如果用户没有设置User-Agent,系统默认则为python的版本号。
3. 打开探针对页面上要爬取的内容做初步的定位,找到数据对应的位置的标签,便于后期对所需内容的检索。 图
数据解析的方式较多,现在用的比较多的有:
1. 正则表达式,在python中可以利用re模块进行处理。
2. Xpath ,它是一门在 XML 文档中查找信息的语言,可用来在 XML 文档中对元素和属性进行遍历。
3. BeautifulSoup4, 简称BS4,该程序包提供了多个解析器,能够完成不同场景下的数据的解析,在项目中采用此数包。程序包提供了便捷的信息查询函数,通常使用find()和find_all()函数。
import urllib.request
from bs4 import BeautifulSoup as bs
import re
import xlwt
import pandas as pd
import os
import matplotlib.pyplot as plt
import numpy as np
#利用正则表达式过滤
#影片链接
findlink = re.compile(r'')
#电影图片链接
findimgsrc = re.compile(r',re.S)#让换行符包含在字符中
#片名
findtitle = re.compile(r'(.*)')
#影片的评分
findrating = re.compile(r' ')
#评价人数
findcont =re.compile(r'(\d*)人评价')
#影片概述
findinq = re.compile(r'(.*)',re.S)
#影片的相关内容
finddb = re.compile(r'(.*?)
',re.S)
爬取网页,注意
将下面标记注意处
修改为自己电脑的用户代理。如果是,谷歌浏览器输出chrome://version/即可。
#爬取网页
def askURL(url):
'''
爬取网页,获得网页的全部内容
:param url:爬取网站
'''
#注意:****修改为自己电脑的用户代理*****
head = {
"User-Agent": "***************"#用引号括起来
}
#用户代理:告诉浏览器自己的浏览器类型
req = urllib.request.Request(url,headers=head)
try:
resp = urllib.request.urlopen(req)
html = resp.read().decode('utf-8')
#print(html)
except urllib.error.URLError as e:
if hasattr(e,"code"):
print(e.code)
if hasattr(e,"reason"):
print(e.reason)
return html
对爬取的html文件进行解析。使用BeautifulSoup定位特定的标签位置,再使用正则表达式找到具体的内容。我们需要的每个电影数据都在一个 爬取到的数据类型有文字和图片,将图片数据存入文件夹中,将文字数据存入Excel表格中,便于后期的查看和进一步的处理。 下载进度可视化处理 在解析内容时我们获取了电影图片的链接,利用urllib.request.urlretrieve()下载指定url内容到本地,在存入之前,需要对文件进行判断,如果文件已存在,则无需下载。 依次运行函数即可得到数据和结果。 将列表中的字符串数据存入csv文件中,数据一共有8栏,采用排好的顺序记录着豆瓣top250数据的相关信息。 将下载的图片存入文件中,在存入电影封面文件之前,需要先指定文件夹的位置,程序将每张图片命名为“片名+排名”的形式,方便进一步的处理。#获取数据,解析得到数据列表
def get_data(baseurl):
'''
使用正则表达式约束,得到想要爬取的内容
:param baseurl:基本网址
'''
talist = []
for i in range(0,10):
url = baseurl+str(i*25) #网页自动翻页
html=askURL(url) #保存获取到的数据
#解析内容
soup = bs(html,"html.parser")
for item in soup.find_all('div',class_="item"):
data = [] #每个影片的数据
item = str(item)
#影片链接
link = re.findall(findlink,item)[0]
data.append(link)
#image link
imsrc = re.findall(findimgsrc,item)[0]
data.append(imsrc)
#title
tt = re.findall(findtitle,item)
if(2==len(tt)):
ctt = tt[0] #中文名
data.append(ctt)#add chinese title
#ett外文名
ett = re.sub('/','',tt[1])#remove /
ett = re.sub('\xa0','',ett)#remove \xa0
data.append(ett) #add other title
else:
data.append(tt[0])
data.append(" ")
#related info
inf = re.findall(finddb,item)[0]
inf = re.sub("
(\s+)?"," ",inf)#remove
inf = re.sub('/'," ",inf) #去除/
inf = inf.strip() #去掉前后的空格
inf = inf.replace('\xa0','')#去除\xa0
data.append(inf)
datalist.append(data) #将数据存入datalist
print(datalist)#测试
return datalist
整理文档
注意将下面代码path
修改为自己想要存储的位置。#整理文档
def list2xlwt(url):
'''
将列表中的数保存至csv文件中
:param url:网站链接
'''
li = get_data(url)#爬取得到的数据
columns = ["影片链接", "图片链接","中文片名","其他片名",'影片的评分','参评人数','影片概述','影片相关内容']#栏目名
dt = pd.DataFrame(li, columns=columns)
#注意:****必须自定义文件路径****
path = "D:/WeChat/biancheng/exercise/py/tydpy/2-数据分析处理库pandas/nlp/spider/豆瓣top250.csv"
if not os.path.exists(path): #传入绝对路径
dt.to_csv(path,index=0)#保存文件
else:
print('文件已存在!')
return path
显示下载进度条
#下载进度条
def progress_bar(a,b,c):
'''
显示下载进度
:param a:已经下载的数据块
:param b:数据块的大小
:param c:远程文件的大小
'''
per = a * b*100.0 /c
if per>100:
per=100
print("\rdownloading:%5.1f%%"% per,end='\t')
批量下载图片
注意将下面代码strn
修改为自己想要存储的位置。#批量下载图片
def download_img(path):
'''
下载图片并且保存在文件夹中
:param path:文件下载路径
'''
df = pd.DataFrame(pd.read_csv(path,header=0))
x = df['图片链接'].values #图片链接一栏
y=df['中文片名'].values #影片中文名
for i in range(250):
#注意:****自定义路径****
#判断文件是否存在,如果不存在就下载
strn = 'D:/WeChat/biancheng/exercise/py/tydpy/2-数据分析处理库pandas/nlp/spider/image/'+y[i]+str(i)+'.jpg'#image name
if not os.path.isfile(strn):
urllib.request.urlretrieve(x[i],strn,progress_bar) #爬取图片
print('download finished!')
else:
print('文件已存在!')
分析数据部分
def further_process(path):
'''
进一步处理,绘制电影的top250的评分柱状图
:param path:文件下载路径
'''
df = pd.DataFrame(pd.read_csv(path,header=0))
x = df['影片的评分'].values #影片的评分一栏
y = df['参评人数'].values #参评人数一栏
#评分绘图
plt.figure(figsize=(14, 10), dpi=80)
idx = np.arange(1,len(x)+1)
plt.plot(idx,x,color='red')
p2 = plt.bar(idx, x,label="score", color="#87CEFA")
plt.xlabel('top250')
plt.ylabel('Movie scores')
plt.ylim([0,12])
plt.title('Movie ratings')
plt.legend(loc="upper right")
plt.show()
结果
def main():
# url = "http://movie.douban.com/top250?start=" #网址
# path=list2xlwt(url) #保存至csv文件
# download_img(path) #爬取图片
#输入你所存储的表格的位置
path = "D:/WeChat/biancheng/exercise/py/tydpy/2-数据分析处理库pandas/nlp/spider/豆瓣top250.csv"
further_process(path)
if __name__=="__main__":
main()