zoukankan      html  css  js  c++  java
  • 初识爬虫——游天下 租房信息

    昨今两天,学习了基本的爬虫,感觉很不错,写下分享分享!!!

    首先,大家都关心的问题,学习爬虫需要具备什么知识呢??大致如下:

    • python的基础知识(函数的定义、列表的操作、文件操作、正则表达式)难度:***
    • python额外知识(BeautifulSoup、requests、re(正则表达式))
    • html+css的基础知识(类选择器、id选择器以及dom)难度:******

    然后就是做应该爬虫的基本流程:

    1. 明确自己的目标,在哪个网站爬取什么数据
    2. 分析单个页面中所需数据的获取规律
    3. 将规律提炼成函数
    4. 循环遍历获取数据
    5. 保存数据
    6. 分析数据

    比如,假设我们的任务如下:

    通过这张图片我们可以获得至少两个很重要的信息:

    1. 目标网站
    2. 目标数据

    接下来就是如何去制作爬虫,故,我们要去学习相关的工具:

    1. BeautifulSoup(https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/)
    2. requests(https://cn.python-requests.org/zh_CN/latest/)

    然后,我们就可以对单个页面的数据进行分析了。例如:http://www.youtx.com/chengdu/page1/

    首先我们在浏览器中输入地址:

    然后,我们可以(这里以chrome浏览器为例)按下F12,得到下面的画面:

    然后,我们点击那个箭头:

    然后,选取我们想看的部分,比如:

    我们就先点击刚刚那个箭头,然后点击那个地方,得到如下:

    图中箭头所指即使该租房的主要信息页面,然后,我们就点进去看看:

    这儿就是我们爬虫最主要的操作空间了,我们所需要的许多信息都是从这里获取的
    还是上面说的那样,我们先按F12,然后点击箭头,然后点击我们关注的那个地方,比如说:

    我们可以通过观察html页面知道它的位置,然后,接下来的一步就是我们怎样去找到它,如果我们仔细观察,就会发现下面的信息:

    我们可以发现,它是位于class为housemessage的li的下面的,于是我们知道,如果我们要获取那个内容,就要先获取那个li标签再获得内容。
    在css中我们知道,一个类选择器可以对应着多个标签,但是一个id选择器则只能对应一个标签,于是,我们需要知道该类选择器作用于那些标签,于是,我们可以用下面的方法做(涉及js)

    然后:

    我们发现刚好只有一个,可省下了不少事情。
    通过上面的分析,于是我们知道了一个大致的思路:在html中获取类名为housemessage的元素 ——>获取需要的值。
    那么问题来了,我们如何得到html页面,且如何获取元素呢,获取元素后我们如何获取它的值呢???
    这里,我们就需要开始使用bs4模块和requests模块了。

    以www.baidu.com为例:

    # 第一步 导包
    import requests
    from bs4 import BeautifulSoup
    
    # 第二步 获取目标网页的源代码
    source = requests.get('www.baidu.com')
    # 这里我们可以看看source具有哪些方法和属性
    print(dir(source))
    print(source.__dict__)
    
    # 第三步 美化源代码
    soup = BeautifulSoup(source.text, 'html.parser')
    # 看看效果
    print(soup.prettify())
    
    # 第四步 获取标签
    print(soup.select(xxxx))
    
    # 第五步 获取标签的值
    print(soup.select(xxx).__dict__['contents'])
    
    

    通过以上,我们就可以在一个页面中获取我们想要的数据了,那么多个页面爬取也就简单了,可以去寻找每一个页面的规律,通过上面的方法,遍历获取每个页面中理解,打开,获取数据,也可以是继续获取连接,一步步深入。

    以下就是完成上述任务的代码,可以参考参考,若有不足,请指正!!!谢谢!!!

    补充一下:爬取数据我们可以在云服务器上定时爬取,这样可以简化我们的工作。请参考:https://www.cnblogs.com/JonnyJiang-zh/p/14166913.html
    ·

    # -*- coding:UTF-8 -*-
    """
    Created on 2020/12/19 16:40
    
    @author : Jonny Jiang
    """
    
    
    import requests
    import re
    from bs4 import BeautifulSoup
    import csv
    import sys
    import time
    
    def get_info(url):
        content = requests.get(url)
        soup = BeautifulSoup(content.text, 'html.parser')
        housepercity = None  # 市
        housedistrict = None  # 区
        house_area = None  # 面积
        bedroom_num = 0 # 卧室数量
        bathroom_num = 0 # 卫生间数量
        house_style = None  # 房屋户型
        amount = None  # 宜住人数
        today_price = None  # 今日价格
        owner = None  # 租房人
        money = None  # 是否收取押金
        days = None  # 最短入住天数
        score = 0  # 总体评价
        result = []
    
        # 市区匹配表达式
        addr_1_p = "housepercity = (.+);"
        addr_2_p = "housedistrict = (.+);"
    
        housepercity = re.findall(re.compile(addr_1_p), soup.prettify())[0]
        housedistrict = re.findall(re.compile(addr_2_p), soup.prettify())[0]
        house_area = re.findall('d+', soup.select('.housemessage span')[2].contents[0])[0]
        bedroom_num = re.findall('d+', soup.select('.housemessage span')[-3].contents[0])
        if not bedroom_num:
            bedroom_num = 0
        else:
            bedroom_num = bedroom_num[0]
        bathroom_num = re.findall('d+', soup.select('.housemessage span')[1].contents[0])
        if not bathroom_num:
            bathroom_num = 0
        else:
            bathroom_num = bathroom_num[0]
        house_style = (bedroom_num, bathroom_num)
        amount = re.findall('d+', soup.select('.housemessage span')[-3].contents[0])[0]
        today_price = soup.select('.part-two p span')[0].__dict__.get('contents')[1]
        owner = soup.select(".left a")[0].__dict__['attrs']['title']
        money = soup.select('.dsection-4 span')[-4].__dict__['contents'][0][1:]
        days = soup.select('.dsection-4 span')[2].__dict__['contents'][0][0]
        score_s = soup.select('.sec-1 div')[0].get('class')
        score_int = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'half': 0.5}
        tmp = ''
        if len(score_s) > 1:
            for s in score_s[1][:-4]:
                tmp += s
                if tmp in score_int:
                    score += score_int[tmp]
                    tmp = ''
        result = [housepercity, housedistrict, house_area, house_style, amount, today_price, owner, money, days, score]
    
        return result
    
    
    def main():
        page_url = 'http://www.youtx.com/chengdu/page{}/'
    
        # 保存文件名
        filename = 'test.csv'
        # 开始写入
        # filename = sys.argv[1]
        f = open(filename, 'w+', encoding='utf-8')
        csv_writer = csv.writer(f)
        csv_writer.writerow(['市', '区', '房屋面积', '房屋户型', '宜住人数', '当日出租价格', '租房人', '是否收取押金', '最短入住时间', '总体评价'])
    
        try:
            for i in range(1, 33):
                now_url = page_url.format(i)
                page = requests.get(now_url)
                soup = BeautifulSoup(page.text, 'html.parser')
                url_markups = soup.select('#results>ul>li')
                for url_markup in url_markups:
                    url = url_markup.a.get('href')
                    print(url)
                    next_page = url
                    result = get_info(next_page)
                    print(result)
                    csv_writer.writerow(result)
                    time.sleep(0.5)
        finally:
    
            # 结束写入
            f.close()
    
    
    if __name__ == '__main__':
        main()
    
  • 相关阅读:
    java_web连接SQL_server详细步骤
    探索需求-设计前的质量之二
    EF三种编程方式详细图文教程(C#+EF)之Code First
    EF三种编程方式详细图文教程(C#+EF)之Model First
    EF三种编程方式详细图文教程(C#+EF)之Database First
    探索需求-设计前的质量之一
    编写有效用例之三
    编写有效用例之二
    golang 环境安装
    golang 命令详解
  • 原文地址:https://www.cnblogs.com/JonnyJiang-zh/p/14161852.html
Copyright © 2011-2022 走看看