python 爬虫-链家租房信息

爬虫,其实就是爬取web页面上的信息。

Python 爬取手机版安居客 爬虫爬取房源信息_python


Python 爬取手机版安居客 爬虫爬取房源信息_html_02

## python库

Python库

1.request 用来获取页面内容
2.BeatifulSoup

request文档链接:
https://requests.readthedocs.io/zh_CN/latest/user/quickstart.html BeatifulSoup文档链接:
https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html

先安装这两个包

安装requests和BeautifulSoup:

跟上篇同样的方法,安装成功的界面如下:
安装代码:

pip install requests

Python 爬取手机版安居客 爬虫爬取房源信息_Python 爬取手机版安居客_03

代码:pip install bs4

Python 爬取手机版安居客 爬虫爬取房源信息_Python 爬取手机版安居客_04


同样检查一下:

Python 爬取手机版安居客 爬虫爬取房源信息_python_05

代表安装成功了。遇到问题:python还是无法识别requests库。百度了一下。解决办法如下:

打开Python文件的安装目录,进入Scripts文件中,按住Shift键+鼠标右击,选择【在此处打开Powershell窗口】

Python 爬取手机版安居客 爬虫爬取房源信息_Python 爬取手机版安居客_06

可以看到,requests的确存在了。

此时进入python,点击file-settigngs,选择【Project Interpreter】,在右边的列表里可以看到已经安装的各种库、对应的版本以及最新版本,然后点击 + 号,搜索报错的那个库,比如本文的 requests 库,选中后点击【Install Package】安装库,安装成功后右下角会有提示 Packages installed successfully,再次运行程序就没有报错了!

同理下载bs4。

运行结果:

Python 爬取手机版安居客 爬虫爬取房源信息_Python 爬取手机版安居客_07


原博:


import requests
from bs4 import BeautifulSoup
url = "https://gz.lianjia.com/zufang/"
responce = requests.get(url)
soup = BeautifulSoup(responce.text,'lxml')
# print(responce.text)
print(soup)

运行时报错:

bs4.FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library? 解决:原因是没有下载lxml需要的东西,下载一个就好了。

Python 爬取手机版安居客 爬虫爬取房源信息_ide_08

下载完之后,from bs4 import BeautifulSoup是不报错了,但是运行之后还是报错,把lxml改为html.parser,运行结果没有问题!

import requests
from bs4 import BeautifulSoup
url = "https://gz.lianjia.com/zufang/"
responce = requests.get(url)
soup = BeautifulSoup(responce.text,'html.parser')
# print(responce.text)
print(soup)

原博:

打开网页,右键,检查,看到这行颜色变了,找到div class的名字是content__list–item–main。

Python 爬取手机版安居客 爬虫爬取房源信息_python_09


代码这么写:

links_div = soup.find_all('div', class_="content__list--item--main")
# links = [for div in links_div]
print(links_div)   #里面存了一个列表
# print(links_div[0])   #查看第一个
# print(links)

运行结果:

Python 爬取手机版安居客 爬虫爬取房源信息_ide_10

查看列表其中一个元素,这里查看第一个:

Python 爬取手机版安居客 爬虫爬取房源信息_html_11


但是我们只想要链接,不要图片等其他的信息,也就是a href后面的链接,代码如下:

links_div = soup.find_all('div', class_="content__list--item--main")
links = [div.a.get('href') for div in links_div]
# print(links_div)   #里面存了一个列表
# print(links_div[0].a.get('href'))   #查看第一个
print(links,len(links))

此时,我们就获取到了当前页面的全部链接,长度为33。

Python 爬取手机版安居客 爬虫爬取房源信息_Python 爬取手机版安居客_12

封装成函数,作用是获取列表页下面的所有租房页面的链接,返回一个链接列表

def get_links(url):
    responce = requests.get(url)
    soup = BeautifulSoup(responce.text, 'html.parser')
    links_div = soup.find_all('div', class_="content__list--item--main")
    links = [div.a.get('href') for div in links_div]
    return links

url = "https://gz.lianjia.com/zufang/"
print(get_links(url))
结果相同:
['/zufang/GZ2298305088701612032.html', '/zufang/GZ2381801160471756800.html', '/zufang/GZ2359884100317757440.html', '/apartment/7268.html', '/zufang/GZ2499974203789549568.html', '/apartment/19264.html', '/zufang/GZ2499100907166777344.html', '/zufang/GZ2499209752543248384.html', '/zufang/GZ2497822820261183488.html', '/zufang/GZ2497607240542846976.html', '/zufang/GZ2498431143112876032.html', '/zufang/GZ2310049470823809024.html', '/zufang/GZ2499346361594953728.html', '/zufang/GZ2392521977211928576.html', '/zufang/GZ2499056259253411840.html', '/zufang/GZ2500010005773172736.html', '/zufang/GZ2500031132138217472.html', '/zufang/GZ2499288504467996672.html', '/zufang/GZ2499020325493145600.html', '/zufang/GZ2499120229419065344.html', '/zufang/GZ2499377558819717120.html', '/zufang/GZ2378856616616534016.html', '/zufang/GZ2497621306694959104.html', '/zufang/GZ2330296981744271360.html', '/zufang/GZ2497812365010010112.html', '/zufang/GZ2354164126701592576.html', '/zufang/GZ2497645065968041984.html', '/zufang/GZ2334517367570710528.html', '/zufang/GZ2321645290765434880.html', '/zufang/GZ2362854688652525568.html', '/zufang/GZ2344044030008238080.html', '/zufang/GZ2325288593729257472.html', '/zufang/GZ2354875364645543936.html']

点进其中一个页面,https://gz.lianjia.com/zufang/GZ2298305088701612032.html?nav=0&unique_id=dd85aae4-ba2d-46af-a027-1b5a920a1b70zufang1589621537856,检查元素,点击图片左上角的箭头,这样我们点到页面哪个地方,都会相对应定为到查看器哪个地方。比如点到租金2000元,定位到了<span>那一行,没有class,怎么办呢?试着把class写成上一行的content__aside–title,结果可以爬到,可是多了一些,用字符串截取一下。

Python 爬取手机版安居客 爬虫爬取房源信息_Python 爬取手机版安居客_13


Python 爬取手机版安居客 爬虫爬取房源信息_Python 爬取手机版安居客_14

接下来一点点提取面积、楼层等信息。

Python 爬取手机版安居客 爬虫爬取房源信息_Python 爬取手机版安居客_15

租金

点到租金2000元,定位到了<span>那一行,没有class,怎么办呢?试着把class写成上一行的content__aside–title,结果可以爬到,可是多了一些,用字符串截取一下。

# 获取url下的页面内容,返回soup对象
def get_page(url):
    responce = requests.get(url)
    soup = BeautifulSoup(responce.text, 'html.parser')
    return soup

# 封装成函数,作用是获取列表页下面的所有租房页面的链接,返回一个链接列表
def get_links(link_url):
    soup = get_page(link_url)
    links_div = soup.find_all('div', class_="content__list--item--main")
    links = [div.a.get('href') for div in links_div]
    return links

house_url = 'https://gz.lianjia.com/zufang/GZ2298305088701612032.html?nav=0&unique_id=' \
            'dd85aae4-ba2d-46af-a027-1b5a920a1b70zufang1589621537856'
soup = get_page(house_url)
# print(soup.find('div', class_='content__aside--title').text)
price = soup.find('div', class_='content__aside--title').text
print(price[1:8])

.text可以打印出我们真正想要获取的文本。运行结果:

Python 爬取手机版安居客 爬虫爬取房源信息_python_16


最后把这个结果赋值给price。截取后刚好爬到租金!

Python 爬取手机版安居客 爬虫爬取房源信息_mysql_17

因为这里的单位已经跟价格一起显示了,所以不用单独再写代码爬了。如果要写的话,跟价格时一样的,比如

# unit = soup.find('span', class_='total').text
# unit.strip()

合并:

unit = soup.find('span', class_='total').text.strip()

意思是一样的。strip函数可以把两边的空格删除。

面积:

点击面积,定位到下图的地方,是一个列表的样式,这时我们find_all就好了。

Python 爬取手机版安居客 爬虫爬取房源信息_python_18

代码如下:

house_info = soup.find_all('li',class_='fl oneline')
print(house_info)

打印house_info看一下:

Python 爬取手机版安居客 爬虫爬取房源信息_html_19

所有的租房信息都出现了。

但我们只要文本,打印住房面积看一下:

print(house_info[1].text)

结果:

Python 爬取手机版安居客 爬虫爬取房源信息_html_20


但是“面积:”这三个字符我们是不需要的,截取掉:

print(house_info[1].text[3:])

结果:

Python 爬取手机版安居客 爬虫爬取房源信息_Python 爬取手机版安居客_21

把面积赋给area

area = house_info[1].text[3:]

朝向

第二个信息是朝向,同样的代码:

chaoxiang = house_info[2].text[3:]

结果:

Python 爬取手机版安居客 爬虫爬取房源信息_ide_22

没有问题!

维护

第三个是维护。

入住

同上。

chaoxiang = house_info[2].text[3:]
weihu = house_info[4].text[3:]
ruzhu = house_info[5].text[3:]
louceng = house_info[7].text[3:]
dianti = house_info[8].text[3:]
print(chaoxiang, weihu, ruzhu, louceng)

暂时爬这几个。

Python 爬取手机版安居客 爬虫爬取房源信息_python_23

租赁方式

自己试着爬了租赁方式这块的信息,定位到检查元素,同样是find_all

Python 爬取手机版安居客 爬虫爬取房源信息_Python 爬取手机版安居客_24

Python 爬取手机版安居客 爬虫爬取房源信息_mysql_25

如果把class成label,只要爬到下图:

Python 爬取手机版安居客 爬虫爬取房源信息_html_26

试了一下把class写成content__aside__list,也就是蓝色的地方。

lease = soup.find_all('ul', class_='content__aside__list')
# lease = soup.find_all('span', class_='label')
print(lease)

Python 爬取手机版安居客 爬虫爬取房源信息_html_27

这样才能爬到完整的信息。

在后面加上text想只保留文字
注意!不能直接lease.text,因为lease是find_all出来的一个列表,不是find函数,如果是price就可以直接在后面加 .text

price = soup.find('div', class_='content__aside--title').text

但是find_all不行,要先指定其中一个元素:

lease = soup.find_all('ul', class_='content__aside__list')
# lease = soup.find_all('span', class_='label')
print(lease[0].text)

这样文字就出来了:

Python 爬取手机版安居客 爬虫爬取房源信息_ide_28

同样的,"租赁方式:"这五个字符不需要,截取掉:

print(lease[0].text[6:])

这样打印出来的就是整租两个字了。
这里因为lease[0]就是全部文字,所以一个个截取出来。

print(lease[0].text[6:9],lease[0].text[14:25],lease[0].text[30:40])

结果:

Python 爬取手机版安居客 爬虫爬取房源信息_python_29

把所有信息打印看一下:

info = {
    '价格':price,
    '面积':area,
    '朝向':chaoxiang,
    '维护':weihu,
    '入住':ruzhu,
    '楼层':louceng,
    '电梯':dianti,
    '租赁信息':lease_info
}
print(info)

结果:

{'价格': '2000元/月', '面积': '73㎡', '朝向': '东北', '维护': '今天', '入住': '随时入住', '楼层': '高楼层/6层', '电梯': '无', '租赁信息': ('整租\n', '2室1厅1卫 73㎡\n', '东北 高楼层/6层\n')}

对房屋信息进行封装

1.先在navicat把表格建好

Python 爬取手机版安居客 爬虫爬取房源信息_html_30

2.把连接数据库函数也封装一下

DATABASE = {                   #一个数据库,写成字典;如果是多个数据库连接,写成列表[{配置信息},{}]
    'host':'localhost',    #localhost相当于127.0.0.1,如果是远程数据库,此处为远程服务器的ip地址
    'database':'lj',
    'user':'root',
    'password':'1234'
}
def get_db(setting):
    return pymysql.connect(**setting)

def insert(db, house):
    values = "'{}',"*7 +"'{}'"
    sql_values = values.format(house['价格'],house['面积'],house['朝向'],house['维护'],
                               house['入住'],house['楼层'],house['电梯'],house['租赁信息'])
    sql = """
    insert into house(price,area,chaoxiang,weihu,ruzhu,louceng,dianti,lease_info)
     values({});
    """.format(sql_values)
    print(sql)
    cursor = db.cursor()
    cursor.execute(sql)
    db.commit()

3.插入数据库

house = get_house_info('https://gz.lianjia.com/zufang/GZ2298305088701612032.html?'
                       'nav=0&unique_id=dd85aae4-ba2d-46af-a027-1b5a920a1b70zufang1589621508886')
# print(house)
db = get_db(DATABASE)
insert(db,house)

因为租赁信息是个元组,插入数据库总是报错,我改成了text,把没有截取的整段文字传进去了。如图:

Python 爬取手机版安居客 爬虫爬取房源信息_ide_31

4.爬取多条信息

db = get_db(DATABASE)
links = get_links('https://gz.lianjia.com/zufang/')
for link in links:
    time.sleep(2)
    print("获取一个房子信息成功")
    house = get_house_info(link)
    # print(house, end='\r')
    insert(db,house)

最后爬取成功

Python 爬取手机版安居客 爬虫爬取房源信息_html_32