python爬虫

实验  爬虫实验

  • 实验环境:

Windows10系统、pycharm软件

  • 实验步骤

(1)导包

import re #正则表达式,进行文字匹配

from bs4 import BeautifulSoup#网页解析,获取数据

import urllib.request,urllib.error #制定URL,获取网页数据

import xlwt #进行excel操作

import sqlite3 #进行SQLLite数据库操作

(2)爬取数据

首先要了解链家的网页结构,总结合适的正则表达式

我们可以发现网页中包含浦东-金桥-嘉泷汇的源代码为:

浦东

金桥

嘉泷汇

然后根据网页结构编写正则表达式

(3)解析数据

此处用到bs4库

由于我们解析的是HTML格式,所以我们使用的是html.parser,然后使用find_all函数查找符合的字符串

使用re库通过正则表达式查找到指定的字符串后,运用data.append语句将字符串加入到data中。

对于一定有的条件比如地址等,我们在该语句后可以写上 '[0]',也就是说如果是列表就从第0个开始爬取,对于不一定有的特点就需要稍加判断。

(4)存储数据

将网页爬取到的数据存储起来

由于我们是爬虫,所以当多次爬取时可能会被网站禁止,因此我们需要给我们的爬虫做一下伪装,比如加一个网页头,假装我们是网页,这样就不容易被封啦。

  • 实验结果:

(1)实验代码:

import re  # 正则表达式,进行文字匹配
from bs4 import BeautifulSoup  # 网页解析,获取数据
import urllib.request, urllib.error  # 制定URL,获取网页数据
import xlwt  # 进行excel操作
import sqlite3  # 进行SQLLite数据库操作

# 区域
findplace1 = re.compile(
   
r'(.*)-.*-.*'# 创建正则表达式对象,表示规则(字符串的模式)

findplace2 = re.compile(
   
r'.*-(.*)-.*')

findplace3 = re.compile(
   
r'.*-.*-(.*)')

# 房子大小
finddaxiao = re.compile(r'/(.*)/.*/.*', re.S)  # re.s让换行符包含在字符中
# 房子朝向
findfangxiang = re.compile(r'/.*/(.*)/.*', re.S)
# 房子规格
findguige = re.compile(r'/.*/.*/(.*)', re.S)
# 楼层类型
findleixing = re.compile(
    
r'

.*/(.*).*

.*

',
    re.S)

# 是否靠近地铁
findsubway = re.compile(r'(.*)')
# 是否是精装
finddecoration = re.compile(r'(.*)')
# 是否可以随时看房
findkey = re.compile(r'(.*)')
# 是否是新上的
findnew = re.compile(r'(.*)')
# 维护时间
findtime = re.compile(r'(.*)')
# 平均租金
findmoney = re.compile(r'(.*)')


def getData(baseurl):  # 调用获取页面信息的函数
   
datalist = []  # 分配暂存的空间
   
for i in range(0, 100):
        url = baseurl +
str(i)
        html = askURL(url) 
# 保存获取到的网页源码
       
# print(html)    #测试用的代码

       
# 逐一解析数据(边获取边解析)
       
soup = BeautifulSoup(html, "html.parser"# html.parserhtml的解析器
       
for item in soup.find_all('div', class_="content__list--item"):  # 查找符合要求的字符串,形成列表
           
# print(item) #测试:查看链家item全部信息
           
data = []
            item =
str(item)  # 转换成字符串,否则无法识别
           
# 链家详情链接

           
lianjie2 = "https://sh.lianjia.com/zufang/"
           
lianjie = lianjie2
            data.append(lianjie) 
# 添加链接

           
place1 = re.findall(findplace1, item)[0# re库用来通过正则表达式查找指定的字符串
           
place2 = re.findall(findplace2, item)[0]
            place3 = re.findall(findplace3, item)[
0]
            place = place1 +
'-' + place2
            data.append(place) 
# 添加地址

           
data.append(place3)  # 添加小区

           
daxiao = re.findall(finddaxiao, item)[0]
            daxiao = daxiao.strip()
            data.append(daxiao.replace(
"", ""))  # 添加房子大小(平米)并替换前后空格

            
fangxiang = re.findall(findfangxiang, item)[0]
            data.append(fangxiang.replace(
" ", ""))  # 添加房子朝向并替换空格

           
guige = re.findall(findguige, item)[0]
            data.append(guige.replace(
" ", ""))  # 添加房子户型并替换空格

           
leixing1 = re.findall(findleixing, item)[0]
            leixing2 = leixing1.strip() 
# 去掉前后空格
           
leixing3 = leixing2.replace(" ", ""# 将空格替换掉
           
data.append(leixing3[0:3])  # 添加房子楼层类型并替换空格

           
data.append(leixing3[4:8].replace("层)", ""))  # 添加房子层数并替换掉()

           
subway = re.findall(findsubway, item)  # 可能写有靠近地铁
           
if (len(subway)) != 0:
                subway = subway[
0]
                data.append(subway) 
# 添加近地铁
           
else:
                data.append(
"不靠近地铁"# 添加不靠近地铁

           
decoration = re.findall(finddecoration, item)
           
if len(decoration) != 0:
                decoration = decoration[
0]
                data.append(decoration) 
# 添加精装
           
else:
                data.append(
"不是精装"# 添加不是精装

           
key = re.findall(findkey, item)
           
if len(key) != 0:
                key = key[
0]
                data.append(key) 
# 添加随时看房
           
else:
                data.append(
"不是随时看房"# 添加不是随时看房

           
new = re.findall(findnew, item)
           
if len(new) != 0:
                new = new[
0]
                data.append(new) 
# 添加新上
           
else:
                data.append(
"不是新上"# 添加不是新上

           
time = re.findall(findtime, item)[0]
            data.append(time) 
# 添加维护时间

           
money = re.findall(findmoney, item)[0]
            data.append(money) 
# 添加平均租金(元/月)

           
datalist.append(data)  # data中的数据放入datalist
   
return datalist


def saveData2DB(datalist, dbpath):
    init_db(dbpath)
    conn = sqlite3.connect(dbpath) 
# 链接数据库
   
cur = conn.cursor()  # 游标
   
for data in datalist:
       
for index in range(len(data)):
           
if index == 3 or index == 7 or index == 13# 遇见numeric类型时不转换成"xx"
               
continue
           
data[index] = '"' + data[index] + '"'  # 转换成"xx"
       
sql = '''
                insert into homes (
                info_link,place,xiaoqu,size,chaoxiang,huxing,type,num,subway,decoration,key,new,time,money)
                values(%s)'''
% ",".join(data)
        cur.execute(sql) 
# 执行sql语句
       
conn.commit()  # 提交结果
   
cur.close()  # 关闭游标
   
conn.close()  # 关闭连接

   
print("save....")


def init_db(dbpath):
    sql =
'''
        create table
homes
        (
       
id integer primary key autoincrement,
       
info_link text,
       
place text,
       
xiaoqu text,
       
size numeric,
       
chaoxiang varchar,
       
huxing text,
       
type text,
       
num numeric,
       
subway text,
       
decoration text,
       
key text,
       
new text,
       
time text,
       
money numeric
        )
    ''' 
# 创建数据表
   
conn = sqlite3.connect(dbpath)
    cursor = conn.cursor()
    cursor.execute(sql)
    conn.commit()
    conn.close()



def askURL(url):
    head = { 
# 模拟浏览器头部信息,向链家服务器发送消息
       
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"
   
}
   
# 用户代理,表示告诉链家服务器,我们是什么类型的机器,浏览器(本质上是爬虫)
   
request = urllib.request.Request(url, headers=head)
    html =
""
   
try:
        response = urllib.request.urlopen(request)
        html = response.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


def main():  # 定义主函数
   
baseurl = "https://sh.lianjia.com/zufang/"
   
# 爬取网页
   
datalist = getData(baseurl)
   
# 保存数据
   
dbpath = "lianjia.db"
   
saveData2DB(datalist, dbpath)


if __name__ == "__main__"# 当程序执行时
   
# 调用函数

   
main()

   
print("爬取完毕!")

(2)实验截图:

python爬虫_第1张图片

通过navicat可视工具可查看爬取内容

python爬虫_第2张图片

  • 实验总结:

通过本次实验学习了正则表达式,python爬虫,的相关内容,对数据库的存储和使用也有了进一步的加深。

你可能感兴趣的:(python)