2020-08-09 爬虫心得《第一篇》

一、 爬虫介绍

爬虫是一种自动获取网页内容的程序,是搜索引擎的重要组成部分。网络爬虫为搜索引擎从万维网下载网页。一般分为传统爬虫和聚焦爬虫

二、爬虫步骤

  • 分析网页结构
  • 请求网页数据链接
  • 解析网页和数据元素
  • 数据清洗和可视化分析
  • 保存数据

三、案列《以南京出租房举例》

1.爬虫环境

  1. python
    python下载链接
  2. pycharm
    pycharm下载链接
  3. mysql
    mysql下载链接

2.爬虫网站

分析详情网站

  1. 需求分析
    我们需要抓取它的房源、租期、入住、价格、面积、朝向、楼层、电梯、车位、维护
  2. 解析网页
#可以使用 lxml、BeautifulSoup
列如:
dom=etree.HTML(resp)
soup =BeautifulSoup(resp,'html.parser')
  1. 定位元素
    在这里插入图片描述在这里插入图片描述
#可以使用 xpath、re、BeautifulSoup
我这里使用的BeautifulSoup进行定位的:
 price = soup.find('div', class_="content__aside--title").span.text + '{}'.format("元/月")
    # li=soup.find('ul',class_="content__aside__list")
    ul = soup.find_all('li', class_="fl oneline")
    # 房源
    housingMenu = soup.find('p', class_="content__title").text
    # 朝向
    floorRound = ul[2].text[3:]
    # 面积
    zoomarea = ul[1].text[3:]
    # 维护
    maintain = ul[4].text[3:]
    # 入住
    domain = ul[5].text[3:]
    # 楼层
    floor = ul[7].text[3:]
    # 电梯
    elevator = ul[8].text[3:]
    # 车位
    parkingspace = ul[10].text[3:]
    # 租期
    leases = ul[18].text[3:]

  1. 数据清洗
#我这里把数据装成了字典,一边后面拿出来
 info={
            '房源': housingMenu,
            '租期': leases,
            '入住': domain,
            '价格': price,
            '面积': zoomarea,
            '朝向': floorRound,
            '楼层': floor,
            '电梯': elevator,
            '车位': parkingspace,
            '维护': maintain
        }
  1. 保存数据
#我这里是把他保存到数据库里
def insert_data(db,house):
    values = "'{}'," *9 + "'{}'"
    sql_values = values.format(
        house['房源'],house['价格'],house['入住'],house['租期'],house['面积'],
                                 house['朝向'],house['楼层'],house['电梯'],house[ '车位'],house['维护'])
    sql = '''insert into `housingconnections`(`房源`,`价格`,`入住`,`租期`,`面积`,`朝向`,`楼层`,`电梯`,`车位`,`维护`)
      values({});
      '''.format(sql_values)
    cursor=db.cursor()
    cursor.execute(sql)
    db.commit()

分析主网站

在这里插入图片描述
在这里插入图片描述

'''
https://nj.lianjia.com/zufang/pg1/#contentList
https://nj.lianjia.com/zufang/pg2/#contentList
'''
分析链接,爬取多个页面,以抓取十页为例
可以用 %format
例如:
url='https://nj.lianjia.com/zufang/pg{}/#contentList'
for i in range(1,11):
	url.format(i)
	
for i in range(1,11):
	url='https://nj.lianjia.com/zufang/pg%d/#contentList'%i

如果不理解什么意思可参考:菜鸟教程格式化字符

3.数据库操作

  • 连接数据库
连接数据库首先要开启服务:
net start mysql
关闭服务是:net stop mysql
可以手动进行开启:去搜索框去输入服务找到mysql或者快捷键
win+R 输入 services.msc找到mysql进行开启

在这里插入图片描述

  • 创建数据库和表
create database "数据库名"
create table `表名`
  • 我的数据库语句
CREATE TABLE `housingconnections` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `房源` varchar(50) DEFAULT NULL,
  `价格` varchar(50) DEFAULT NULL,
  `入住` varchar(50) DEFAULT NULL,
  `租期` varchar(50) DEFAULT NULL,
  `面积` varchar(50) DEFAULT NULL,
  `朝向` varchar(50) DEFAULT NULL,
  `楼层` varchar(50) DEFAULT NULL,
  `电梯` varchar(20) DEFAULT NULL,
  `车位` varchar(50) DEFAULT NULL,
  `维护` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

'''
以id为主键(primary key)
其中AUTO_INCREMENT 是自动递增的意思
字符集:ENGINE=InnoDB DEFAULT CHARSET=utf8
'''
  • python操作数据库
'''
我这里使用的是MySQLdb
查询、插入、更新、删除都必须要设立游标
cursor=db.cursor()
运行sql语句
cursor.execute(sql)
'''
1.连接数据库
database={
'host':'127.0.0.1',
'user':'root',
'password':'root',
'db':'es'
}
 db=MySQLdb.connect(host='localhost',user='root',password='root',db='es')
#等价于
db=MySQLdb.connect('localhost','root','root','es')
# 等价于
db=MySQLdb.connect(**database)

2.数据库查询
sql='select * from class'  
3.数据库插入
sql="insert into `class` (`id`, `name`) values ('124', 'chen');"
4.数据库更新
sql="update `class` set `name`='chng' where `id`='123' "
5.数据库删除
sql="delete from `class` where `id`='127'"

4.python代码解释

  • 导入第三方库
import requests
from bs4 import BeautifulSoup
import threading
import MySQLdb
import time
import re
'''
python之所以强大,是因为它的第三方库强大。
可以使用 pip、conda
以request为例
前提:python加入了环境变量,这里就不细说了
命令行输入:快捷键 win + R 输入cmd然后回车
pip install requests
conda install requests
下图展示:我这里是之前装好了
'''

在这里插入图片描述

  • 请求网页链接
headers={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36 Edg/84.0.522.52"
}
def get_page(url):
    resp = requests.get(url, headers=headers).text
    soup =BeautifulSoup(resp,'html.parser')
    return soup

'''
为了防止反爬构造请求头headers
这个网站可以不需要,已经测试过了。
'''
  • 获取多个页面
def get_link(link_url):
    soup=get_page(link_url)
    links_div = soup.find_all('a', class_="content__list--item--aside")
    links = ['{}'.format("https://nj.lianjia.com/") + div.get('href') for div in links_div]
    return links
'''
列表表达式非常方便可以试着用一用
['{}'.format("https://nj.lianjia.com/") + div.get('href') for div in links_div]
'''
  • 主程序开关
if __name__ == '__main__':
    s=time.time()
    db=open_sql(database)
    count = 0
    for i in range(1,10):
        url='https://nj.lianjia.com/zufang/pg{}/#contentList'
        links=get_link(url.format(i))
        for link in links:
            time.sleep(3)
            count+=1
            print('第{}条数据保存成功'.format(count))
            house=parser_page(link)
            process = threading.Thread(target=insert_data,args=(db,house))
            process.start()
    e=time.time()
    print('**************{}条数据保存成功'.format(count),"用时:",e-s)

测试过程中出错处理

在这里插入图片描述

database={
'host': '127.0.0.1',
'user': 'root',
'password': 'root',
'db': 'house',
'charset': 'utf8'
}
'''
需要加入字符集utf8
'''

5.效果展示

在这里插入图片描述

6.源代码展示

# -*- coding: utf-8 -*-
"""
@File    : 南京二手房.py
@Time    : 2020/8/8 21:00
@Author  : xchen-IT
@Email   : [email protected]
@Software: PyCharm
"""

import requests
from bs4 import BeautifulSoup
import threading
import MySQLdb
import time
import re
thread_process=threading.BoundedSemaphore(value=10)
headers={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36 Edg/84.0.522.52"
}
def get_page(url):
    resp = requests.get(url, headers=headers).text
    soup =BeautifulSoup(resp,'html.parser')
    return soup

def get_link(link_url):
    soup=get_page(link_url)
    links_div = soup.find_all('a', class_="content__list--item--aside")
    links = ['{}'.format("https://nj.lianjia.com/") + div.get('href') for div in links_div]
    return links

def parser_page(house_url):
    soup=get_page(house_url)
    price = soup.find('div', class_="content__aside--title").span.text + '{}'.format("元/月")
    # li=soup.find('ul',class_="content__aside__list")
    ul = soup.find_all('li', class_="fl oneline")
    # 房源
    housingMenu = soup.find('p', class_="content__title").text
    # 朝向
    floorRound = ul[2].text[3:]
    # 面积
    zoomarea = ul[1].text[3:]
    # 维护
    maintain = ul[4].text[3:]
    # 入住
    domain = ul[5].text[3:]
    # 楼层
    floor = ul[7].text[3:]
    # 电梯
    elevator = ul[8].text[3:]
    # 车位
    parkingspace = ul[10].text[3:]
    # 租期
    leases = ul[18].text[3:]
    info={
            '房源': housingMenu,
            '租期': leases,
            '入住': domain,
            '价格': price,
            '面积': zoomarea,
            '朝向': floorRound,
            '楼层': floor,
            '电梯': elevator,
            '车位': parkingspace,
            '维护': maintain
        }
    return info


database={
'host': '127.0.0.1',
'user': 'root',
'password': 'root',
'db': 'house',
'charset': 'utf8'
}
def open_sql(setting):
    return MySQLdb.connect(**setting)

def insert_data(db,house):
    values = "'{}'," *9 + "'{}'"
    sql_values = values.format(
        house['房源'],house['价格'],house['入住'],house['租期'],house['面积'],
                                 house['朝向'],house['楼层'],house['电梯'],house[ '车位'],house['维护'])
    sql = '''insert into `housingconnections`(`房源`,`价格`,`入住`,`租期`,`面积`,`朝向`,`楼层`,`电梯`,`车位`,`维护`)
      values({});
      '''.format(sql_values)
    cursor=db.cursor()
    cursor.execute(sql)
    db.commit()

if __name__ == '__main__':
    s=time.time()
    db=open_sql(database)
    count = 0
    for i in range(1,10):
        url='https://nj.lianjia.com/zufang/pg{}/#contentList'
        links=get_link(url.format(i))
        for link in links:
            time.sleep(3)
            count+=1
            print('第{}条数据保存成功'.format(count))
            house=parser_page(link)
            process = threading.Thread(target=insert_data,args=(db,house))
            process.start()
    e=time.time()
    print('**************{}条数据保存成功'.format(count),"用时:",e-s)


'''
分析url
https://nj.lianjia.com/zufang/pg1/#contentList
'''

结束语:博主第一次写博客,望多多指教。。。

猜你喜欢

转载自blog.csdn.net/csdn_java111/article/details/107887734