一、python数据爬虫简介
1.爬虫介绍
爬虫,即网络爬虫,我们可以理解为在网络上爬行的蜘蛛,互联网就比作一张大网,而爬虫便是在这张网上爬来爬去的蜘蛛,如果它遇到想要的资源,就会抓取下来。想抓取什么?这个由我们来控制它。
比如我们想抓取一个网页上面的内容,在这个网中就要有一条道路,其实就是指向网页的地址或者超链接,那么它就可以爬到另一张网上来获取数据。这样,整个连在一起的大网对这个蜘蛛来说触手可及,分分钟爬下来对于我们来说不是事儿。
我们在浏览网页的时候一般情况下打开的是html页面,因此,看到的网页实质是由HTML 代码构成的,爬虫爬来的便是这些内容,通过分析和过滤这些 HTML 代码,实现对图片、文字等资源的获取,也就是所谓的爬虫。
2.爬虫的基本流程
用户获取网络数据的方式:
方式1:浏览器提交请求--->下载网页代码--->解析成页面
方式2:模拟浏览器发送请求(获取网页代码)->提取有用的数据->存放于数据库或文件中
爬虫要做的就是方式2;
流程:
(1)发起请求
使用http库向目标站点发起请求,即发送一个Request
Request包含:请求头、请求体等
Request模块缺陷:不能执行JS 和CSS 代码
(2)获取响应内容
如果服务器能正常响应,则会得到一个Response
Response包含:html,json,图片,视频等
(3)解析内容
解析html数据:正则表达式(RE模块),第三方解析库如Beautifulsoup,scrapy等
解析json数据:json模块
解析二进制数据:以wb的方式写入文件
(4)保存数据
数据库(MySQL,Mongdb、Redis)
3.python常见爬虫的方法
(1)scrapy爬虫
很强大的爬虫框架,可以满足简单的页面爬取(比如可以明确获知url pattern的情况)。用这个框架可以轻松爬下来如亚马逊商品信息之类的数据。但是对于稍微复杂一点的页面,如weibo的页面信息,这个框架就满足不了需求了
2、Beautifulsoup爬虫
整合了一些常用爬虫需求。缺点:不能加载JS
二、使用Beautifulsoup做网络爬虫
1.Beautifulsoup爬虫介绍
Beautiful Soup支持各种html解析器,包括python自带的标准库,还有其他的许多第三方库模块。其中一个就是lxml parser。
借助网页的结构和属性等特性来解析网页的工具,有了它我们不用再去写一些复杂的正则,只需要简单的几条语句就可以完成网页中某个元素的提取
安装方式:pip install beautifulsoup4
2.爬虫数据保存(txt,json,excel,MySQL)(以http://web.jobbole.com/category/css/为例)
# -*- coding:utf-8 -*-
#python网络爬虫,网页内容获取,保存成txt,保存成json,excel,mysql,并进行页面展示
#引入模块
import urllib.request #用来访问url
from bs4 import BeautifulSoup #爬虫
import os #文件管理,文件夹管理
import time #时间模块
import json #json格式管理模块
import codecs #编码转换模块,编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另一种编码。
import xlwt #excel写入模块
import xlrd #excel读取模块
from xlutils.copy import copy #复制页
import pymysql #链接管理MySQL模块
pages=int(input("豆瓣电影250:请输入你要爬取的页数(每页25条,共20页):\n")) #全局变量,获取想要爬取的页数
def getdata():
url="https://movie.douban.com/top250"
#urls=[]
list=[]
#网页格式如“https://movie.douban.com/top250?start=25&filter=”,进行简单运算操作获取每一页的url
for i in range(pages):
#urls.append(str(url)+"?start="+str(i*25)+"&filter=")
myurl=str(url)+"?start="+str(i*25)+"&filter="
res=urllib.request.urlopen(myurl)
response=BeautifulSoup(res,"html.parser")
items=response.find_all("div",{"class":"item"})
for item in items:
dict={}
dict["title"]=item.find("div",{"class":"info"}).find("div",{"class":"hd"}).find("a").find("span").get_text()
#if(item.find("div",{"class":"pic"}).find("a").find("img") is None):
# continue
#else:
dict['href']=item.find("div",{"class":"info"}).find("div",{"class":"hd"}).find("a").get("href")
#dict['details']=item.find("div",{"class":"info"}).find("div",{"class":"bd"}).find("p").get_text().encode("utf-8").decode("utf-8")
dict['quote']=item.find("div",{"class":"info"}).find("div",{"class":"bd"}).find("p",{"class":"quote"}).find("span",{"class":"inq"}).get_text()
dict["img"]=item.find("div",{"class":"pic"}).find("a").find("img").get("src")
list.append(dict)
return list
def savedatatotxt():
mylist=getdata()
folder_name="data"
if not os.path.exists(folder_name):
os.mkdir(folder_name)
cur_data=time.strftime("%Y_%m_%d",time.localtime())
file_name="douban"+cur_data+".txt"
try:
with open(folder_name+"/"+file_name,"w") as fp:
for i in mylist:
fp.write("title"+":"+i['title']+"\n")
fp.write("href"+":"+i['href']+"\n")
fp.write("quote"+":"+i['quote']+"\n")
fp.write("imgUrl"+":"+i['img']+"\n")
except IOError as err:
raise("Error:"+str(err))
finally:
fp.close()
print("数据已成功存入",file_name,"中")
def savedatatojson():
mylist=getdata()
folder_name="data"
if not os.path.exists(folder_name): #检测路径是否存在
os.mkdir(folder_name) #创建路径
cur_data=time.strftime("%Y_%m_%d",time.localtime())
file_name="douban"+cur_data+".json"
try:
with open(folder_name+"/"+file_name,"w") as fp:
for i in mylist:
line=json.dumps(i,ensure_ascii=False)+"\n" #用于将dict类型的数据转成str
fp.write(line)
except IOError as err:
raise("Error:"+str(err))
finally:
fp.close()
print("数据已成功存入",file_name,"中")
def savedatatoexcel():
mylist=getdata()
folder_name="data"
if not os.path.exists(folder_name):
os.mkdir(folder_name)
c_time=time.strftime("%Y-%m-%d",time.localtime())
file_name="douban"+c_time+".xls"
excelname=folder_name+"/"+file_name
workbook=xlwt.Workbook(encoding="utf-8") #创建工作簿,并以UTF8格式操作
sheet=workbook.add_sheet(u'douban数据') #创建工作页,名为“douban数据”
headers=list(mylist[0].keys()) #将字典中的键以列表形式赋值给变量
hStyle=xlwt.easyxf("font:color-index red,bold on") #设置excel格式
for i in range(len(headers)):
sheet.write(0,i,headers[i],hStyle) #第0行,第i列,写入数据headers[i],以hStyle格式
for j in range(1,len(mylist)+1):
for m in range(len(mylist[j-1])):
sheet.write(j,m,mylist[j-1][headers[m]]) #第j行,第m列,写入数据mylist[j-1][headers[m]],以默认格式
workbook.save(excelname) #保存工作簿
print("数据已成功存入",file_name,"中")
def savedatatomysql():
c_connect=pymysql.connect(host="localhost",user="root",passwd="236619",db="douban",port=3306,charset="utf8") #数据库连接
if c_connect:
print("Connection is OK")
mylist=getdata()
for i in mylist:
cur=c_connect.cursor() #游标
#对数据库进行操作
strsql="insert into doubaninfo values (null,%s,%s,%s,%s)" #数据库操作字符串
cur.execute(strsql,(i['title'],i['href'],i['quote'],i['img'])) #为strsql赋值
c_connect.commit() #执行操作
if not cur:
print("error")
if c_connect:
c_connect.close() #关闭连接
print("数据已成功存入doubaninfo中")
def createhtml():
mylist=getdata()
folder_name="html"
if not os.path.exists(folder_name):
os.mkdir(folder_name)
# cur_data=time.strftime("%Y_%m_%d",time.localtime())
file_name="douban.json"
#创建HTML要使用的json格式
try:
with open(folder_name+"/"+file_name,"w",encoding="utf-8") as fp:
fp.write("[")
for i in mylist:
if(i is not mylist[len(mylist)-1]):
line=json.dumps(i,ensure_ascii=False)+",\n"
fp.write(line)
else:
fp.write(json.dumps(i,ensure_ascii=False))
fp.write("]")
except IOError as err:
raise("Error:"+str(err))
finally:
fp.close()
str1='''
豆瓣电影排名
豆瓣电影排名
'''
str3='''
$.ajax({
url:"douban.json",//文件路径
type:"get",//获取文件方式 post(上传,根据参数...)
dataType:"json",
success:function(datas){
var str1=""
for(var i=0;i"+""+""+datas[i].title+""+"
"+
""+
""+datas[i].quote+"
"+"
"+list1[i].quote+"
"+"运行结果如下:
其中MySql表结构如图所示:
网页页面如下: