目录
一、系统环境
二、获取网页
三、解析网页
四、保存数据
一、系统环境
- 语言:Python
- shell平台:jupyter notebook
- 所用库:
import bs4
import re
import urllib.request,urllib.error
import xlwt
from bs4 import BeautifulSoup
import requests
import time
4.库类型:
bs4:(BeautifulSoup4网页解析库)
re:(正则表达式库)
urllib(访问网页库)
xlwt(excel保存库)
二、获取网页
1.添加表头: 为防止服务器识别为爬虫程序。表头信息获取: 访问页面按F12,刷新在network处按暂停,从时间序列首处中找到头文件,里面寻找"User-Agent":信息。
2.设置延迟:使用time函数: time.sleep(1.5),这一步目的为减缓爬虫时间,防止被服务器识别为爬虫程序。
3.使用urllib:urllib.request.Request()。urllib库中访问url函数。
4.获取网页内容:html =response.read().decode("utf-8")。获取网页信息后解码(使用中文格式utf-8)
5.try..except.. 保证程序健壮性,防止出现个别访问无响应报错
代码:
url="https://bj.XXXXX.com/ershoufang/pg"
#得到指定url的网页内容
def askURL(url):
head ={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.72 Safari/537.36"
}
request =urllib.request.Request(url,headers=head)
time.sleep(1.5)
html=""
try:
response =urllib.request.urlopen(request)
html =response.read().decode("utf-8")
return html
except urllib.error.URLError as e:
if hasattr(e,"code"):
return e.code
if hasattr(e,"reason"):
return e.reason
PS:防止被查水表链接隐去了。
三、解析网页
1.正则表达式:
- 何为正则表达式? 你可以理解为一种规则,自定义的规则。它有些一些表述规则(/d表示:数字; . 表示字符; *表示多个;[0-9]表示0-9的一位数;+表示扩展;|表示或关系 ?表示是否存在其他可以网络自行查阅了解) 例:'([0-9]+.[0-9]+)平米' 如 66.88平米,99.11平米 都符合这一规则。
- 为什么要用正则表达式?获取页面后有大量数据,我们需要准确获取有用信息,所以必须制定一种规则。findDistrict =re.compile(r'<img alt="(.*)" class="lj-lazy".*<div class="info clear">') 代码中findDistrict就是一种自定义的规则。其中 r表示 显示获取文本中'/' ,()表示只获取查找到文本中括号内的信息.
2.解析页面:
- 网页信息解析 不同网页内容不同,我所爬取的是一个个模块中的信息。所以我们的思路是 先获取一个个模块,然后在解析一个个模块的内容。
- 获取指定模块信息 每个页面中包含巨大庞杂的信息,这些大多数都是html,css等前端代码。这需要我们去分析代码 找出所需要模块信息 处的<代码标记>。
- 利用工具查找模块 找到标记后 利用BeautifulSoup解析查找,如下例:先将 html值 传入bs中,然后利用bs.findAll()查找模块内容。
soup = BeautifulSoup(html,"html.parser")
for item in soup.findAll('li',class_="item salelist"):
print(item)
- 解析模块中所需信息 :利用正则表达式规则,解析出模块所需信息。District = re.findall(findDistrict,item)[0] (后面[0]指是获取信息中相同部分的第一个)
- 储存模型有用信息:首先用列表 data[] 把模块中信息data.append()添加进去,储存完模块中所以信息的data。再将模块data,添加进datalist中。datalist中所含全部模块信息了。
finditems =re.compile(r'<div class="address"><div class="houseInfo"><span class="houseIcon"></span>(.*)</div></div><div class="followInfo"><span class="starIcon"></span>')
findPrice=re.compile(r'<div class="unitPrice" .*><span>(.*)</span></div></div></div><div class="listButtonContainer">')
findDistrict =re.compile(r'<img alt="(.*)" class="lj-lazy".*<div class="info clear">')
findId =re.compile(r'<div class="compareBtn LOGCLICK" data-hid="(.*)" data-log_evtid="10230.*">加入对比</div></div></li>')
def getData(baseurl):
datalist = []
pattern = '[0-9]室[0-9]厅'
pattern1 = '([0-9]+.[0-9]+)平米'
pattern2 = '南|西南|南北|东南|北|西北|东北|东|东西|西'
pattern3 = '简装|精装'
pattern4 = '[0-9]+层'
pattern5 = '[0-9][0-9][0-9][0-9]'
coprice ='[0-9]+'
coDistrict ='北京(.*)'
for i in range(0,50):
url=baseurl+str(i)
html =askURL(url)
soup = BeautifulSoup(html,"html.parser")
for item in soup.findAll('li',class_="clear LOGVIEWDATA LOGCLICKDATA"):
data = []
item = str(item)
ID = re.findall(findId,item)[0]
if(ID):
data.append(ID)
else:
data.append("None")
District = re.findall(findDistrict,item)[0]
tDistrict = re.findall(coDistrict, District)
if(District):
data.append(tDistrict)
else:
data.append("None")
items = re.findall(finditems,item)[0]
Layout = re.findall(pattern, items)
Size = re.findall(pattern1, items)
Direction = re.findall(pattern2, items)[0]
Renovation = re.findall(pattern3, items)
Floor = re.findall(pattern4, items)
Floor1 = str(Floor)
Floor2 = re.sub("层","",Floor1)
Year = re.findall(pattern5, items)
if(Layout):
data.append(Layout)
else:
data.append(" ")
if(Size):
data.append(Size)
else:
data.append(" ")
if(Direction):
data.append(Direction)
else:
data.append(" ")
if(Renovation):
data.append(Renovation)
else:
data.append(" ")
if(Floor):
data.append(Floor2)
else:
data.append(" ")
if(Year):
data.append(Year)
else:
data.append(" ")
Price= re.findall(findPrice,item)[0]
tPrice =re.findall(coprice,Price)
if(Price):
data.append(tPrice)
else:
data.append(" ")
datalist.append(data)
return datalist
四、保存数据
- 保存列表数据:使用工具:xlwt.Workbook() #创建一个workbook 设置编码, book.add_sheet()#创建一个worksheet。
- # 写入excel
# 参数对应 行, 列, 值 (如下例) - #保存 路径 我这里写了相对路径 在相关文件下可以找到。(你也可以写绝对路径直接找)
def saveData(datalist):
print("save..........")
book = xlwt.Workbook(encoding="utf-8",style_compression=0)
sheet = book.add_sheet('Lianjia-data',cell_overwrite_ok=True)
col=("Id","District","Layout","Size","Direction","Renovation","Floor","Year","Price")
for i in range(0,9):
sheet.write(0,i,col[i])
for i in range(0,1500):
print("第%d条" %i)
data =datalist[i]
for j in range(0,9):
sheet.write(i+1,j,data[j])
book.save("lianjia999.xls")
应用展示:
datalist = getData(url)
saveData(datalist)
最后演示,完毕。大家尝试觉得有用,不妨点个赞(: