爬虫技术经验总结

目录

一、系统环境

二、获取网页

三、解析网页

四、保存数据

一、系统环境

  1. 语言:Python
  2. shell平台:jupyter notebook
  3. 所用库:
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)

最后演示,完毕。大家尝试觉得有用,不妨点个赞(:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值