精华内容
下载资源
问答
  • 网络爬虫的最终目的就是过滤选取网络信息,最重要的部分可以说是解析器。解析器的优劣决定了爬虫的速度和效率。bs4库除了支持我们上文用过的‘html.parser’解析器外,还支持很多第三方的解析器,下面我们来对他们...
  • 元素审查界面是这样的: ![想要find选中的这个tag]...用bs4直接find()表格里这一行这个tag找不到合适的参数来限定,继续用bs4 find()的话有没有什么办法可以找到吗?
  • 主要介绍了Python爬虫使用bs4方法实现数据解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • Python爬虫入门项目

    万次阅读 多人点赞 2017-12-25 16:26:21
    Python是什么 Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言。 创始人Guido van Rossum是BBC出品英剧Monty Python’s Flying Circus(中文:蒙提·派森的...

    Python是什么

    Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言。

    创始人Guido van Rossum是BBC出品英剧Monty Python’s Flying Circus(中文:蒙提·派森的飞行马戏团)的狂热粉丝,因而将自己创造的这门编程语言命名为Python。

    人生苦短,我用python,翻译自"Life is short, you need Python"

    Python英式发音:/ˈpaɪθən/ ,中文类似‘拍森’。而美式发音:/ˈpaɪθɑːn/,中文类似‘拍赏’。我看麻省理工授课教授读的是‘拍赏’,我觉得国内大多是读‘拍森’吧。

    2017年python排第一也无可争议,比较AI第一语言,在当下人工智能大数据大火的情况下,python无愧第一语言的称号,至于C、C++、java都是万年的老大哥了,在代码量比较方面,小编相信java肯定是完爆其它语言的。

    不过从这一年的编程语言流行趋势看,java依然是传播最多的,比较无论app、web、云计算都离不开,而其相对python而言,学习路径更困难一点,想要转行编程,而且追赶潮流,python已然是最佳语言。

    许多大型网站就是用Python开发的,国内:豆瓣、搜狐、金山、腾讯、盛大、网易、百度、阿里、淘宝、热酷、土豆、新浪、果壳…; 国外:谷歌、NASA、YouTube、Facebook、工业光魔、红帽…

    Python将被纳入高考内容

    浙江省信息技术课程改革方案已经出台,Python确定进入浙江省信息技术高考,从2018年起浙江省信息技术教材编程语言将会从vb更换为Python。其实不止浙江,教育大省北京和山东也确定要把Python编程基础纳入信息技术课程和高考的内容体系,Python语言课程化也将成为孩子学习的一种趋势。尤其山东省最新出版的小学信息技术六年级教材也加入了Python内容,小学生都开始接触Python语言了!!

    再不学习,又要被小学生完爆了。。。

     

    Python入门教程

    Python能做什么

    • 网络爬虫
    • Web应用开发
    • 系统网络运维
    • 科学与数字计算
    • 图形界面开发
    • 网络编程
    • 自然语言处理(NLP)
    • 人工智能
    • 区块链
    • 多不胜举。。。

    Python入门爬虫

    这是我的第一个python项目,在这里与大家分享出来~

    • 需求
      • 我们目前正在开发一款产品其功能大致是:用户收到短信如:购买了电影票或者火车票机票之类的事件。然后app读取短信,解析短信,获取时间地点,然后后台自动建立一个备忘录,在事件开始前1小时提醒用户。
    • 设计
      • 开始我们将解析的功能放在了服务端,但是后来考虑到用户隐私问题。后来将解析功能放到了app端,服务端只负责收集数据,然后将新数据发送给app端。
      • 关于服务端主要是分离出两个功能,一、响应app端请求返回数据。二、爬取数据,存入数据库。
      • 响应请求返回数据使用java来做,而爬取数据存入数据库使用python来做,这样分别使用不同语言来做是因为这两种语言各有优势,java效率比python高些,适合做web端,而爬取数据并不是太追求性能且python语言和大量的库适合做爬虫。
    • 代码
      • 本项目使用python3的版本
      • 获取源码:扫描下方关注微信公众号「裸睡的猪」回复:爬虫入门 获取
         

         

      • 了解这个项目你只需要有简单的python基础,能了解python语法就可以。其实我自己也是python没学完,然后就开始写,遇到问题就百度,边做边学这样才不至于很枯燥,因为python可以做一些很有意思的事情,比如模拟连续登录挣积分,比如我最近在写一个预定模范出行车子的python脚本。推荐看廖雪峰的python入门教程
      • 首先带大家看看我的目录结构,开始我打算是定义一个非常好非常全的规范,后来才发现由于自己不熟悉框架,而是刚入门级别,所以就放弃了。从简而入:
      • 下面咱们按照上图中的顺序,从上往下一个一个文件的讲解init.py包的标识文件,python包就是文件夹,当改文件夹下有一个init.py文件后它就成为一个package,我在这个包中引入一些py供其他py调用。

    init.py

    # -*- coding: UTF-8 -*-  
    
    # import need manager module  
    import MongoUtil  
    import FileUtil  
    import conf_dev  
    import conf_test  
    import scratch_airport_name  
    import scratch_flight_number  
    import scratch_movie_name  
    import scratch_train_number  
    import scratch_train_station  
    import MainUtil
    

    下面两个是配置文件,第一个是开发环境的(windows),第二个是测试环境的(linux),然后再根据不同系统启用不同的配置文件

    conf_dev.py

    # -*- coding: UTF-8 -*-  
    # the configuration file of develop environment  
    
    # path configure  
    data_root_path = 'E:/APK98_GNBJ_SMARTSERVER/Proj-gionee-data/smart/data'  
    
    # mongodb configure  
    user = "cmc"  
    pwd = "123456"  
    server = "localhost"  
    port = "27017"  
    db_name = "smartdb"
    

    conf_test.py

    # -*- coding: UTF-8 -*-  
    # the configuration file of test environment  
    
    #path configure  
    data_root_path = '/data/app/smart/data'  
    
    #mongodb configure  
    user = "smart"  
    pwd = "123456"  
    server = "10.8.0.30"  
    port = "27017"  
    db_name = "smartdb"
    

    下面文件是一个util文件,主要是读取原文件的内容,还有将新内容写入原文件。

    FileUtil.py

    # -*- coding: UTF-8 -*-  
    import conf_dev  
    import conf_test  
    import platform  
    
    
    # configure Multi-confronment  
    # 判断当前系统,并引入相对的配置文件
    platform_os = platform.system()  
    config = conf_dev  
    if (platform_os == 'Linux'):  
        config = conf_test  
    # path  
    data_root_path = config.data_root_path  
    
    
    # load old data  
    def read(resources_file_path, encode='utf-8'):  
        file_path = data_root_path + resources_file_path  
        outputs = []  
        for line in open(file_path, encoding=encode):  
            if not line.startswith("//"):  
                outputs.append(line.strip('\n').split(',')[-1])  
        return outputs  
    
    
    # append new data to file from scratch  
    def append(resources_file_path, data, encode='utf-8'):  
        file_path = data_root_path + resources_file_path  
        with open(file_path, 'a', encoding=encode) as f:  
            f.write(data)  
        f.close
    

    下面这个main方法控制着执行流程,其他的执行方法调用这个main方法

    MainUtil.py

    # -*- coding: UTF-8 -*-  
    
    import sys  
    from datetime import datetime  
    import MongoUtil  
    import FileUtil  
    
    # @param resources_file_path 资源文件的path  
    # @param base_url 爬取的连接  
    # @param scratch_func 爬取的方法  
    def main(resources_file_path, base_url, scratch_func):  
        old_data = FileUtil.read(resources_file_path)   #读取原资源  
        new_data = scratch_func(base_url, old_data)     #爬取新资源  
        if new_data:        #如果新数据不为空  
            date_new_data = "//" + datetime.now().strftime('%Y-%m-%d') + "\n" + "\n".join(new_data) + "\n"      #在新数据前面加上当前日期  
            FileUtil.append(resources_file_path, date_new_data)     #将新数据追加到文件中  
            MongoUtil.insert(resources_file_path, date_new_data)    #将新数据插入到mongodb数据库中  
        else:   #如果新数据为空,则打印日志  
            print(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), '----', getattr(scratch_func, '__name__'), ": nothing to update ")
    

    将更新的内容插入mongodb中

    MongoUtil.py

    # -*- coding: UTF-8 -*-  
    
    import platform  
    from pymongo import MongoClient  
    from datetime import datetime, timedelta, timezone  
    import conf_dev  
    import conf_test  
    
    # configure Multi-confronment  
    platform_os = platform.system()  
    config = conf_dev  
    if (platform_os == 'Linux'):  
        config = conf_test  
    # mongodb  
    uri = 'mongodb://' + config.user + ':' + config.pwd + '@' + config.server + ':' + config.port + '/' + config.db_name  
    
    
    # 将数据写入mongodb  
    # @author chenmc  
    # @param uri connect to mongodb  
    # @path save mongodb field  
    # @data save mongodb field  
    # @operation save mongodb field default value 'append'  
    # @date 2017/12/07 16:30  
    # 先在mongodb中插入一条自增数据 db.sequence.insert({ "_id" : "version","seq" : 1})  
    
    def insert(path, data, operation='append'):  
        client = MongoClient(uri)  
        resources = client.smartdb.resources  
        sequence = client.smartdb.sequence  
        seq = sequence.find_one({"_id": "version"})["seq"]      #获取自增id  
        sequence.update_one({"_id": "version"}, {"$inc": {"seq": 1}})       #自增id+1  
        post_data = {"_class": "com.gionee.smart.domain.entity.Resources", "version": seq, "path": path,  
                     "content": data, "status": "enable", "operation": operation,  
                     "createtime": datetime.now(timezone(timedelta(hours=8)))}  
        resources.insert(post_data)     #插入数据
    

    项目引入的第三方库,可使用pip install -r requirements.txt下载第三方库

    requirements.txt

    # need to install module# need to install module  
    bs4  
    pymongo  
    requests  
    json
    

    下面真正的执行方法来了,这五个py分别表示爬取五种信息:机场名、航班号、电影名、列车号、列车站。他们的结构都差不多,如下:

    第一部分:定义查找的url;
    第二部分:获取并与旧数据比较,返回新数据;
    第三部分:main方法,执行写入新数据到文件和mongodb中;
    

    scratch_airport_name.py:爬取全国机场

    # -*- coding: UTF-8 -*-  
    import requests  
    import bs4  
    import json  
    import MainUtil  
    
    resources_file_path = '/resources/airplane/airportNameList.ini'  
    scratch_url_old = 'https://data.variflight.com/profiles/profilesapi/search'  
    scratch_url = 'https://data.variflight.com/analytics/codeapi/initialList'  
    get_city_url = 'https://data.variflight.com/profiles/Airports/%s'  
    
    
    #传入查找网页的url和旧数据,然后本方法会比对原数据中是否有新的条目,如果有则不加入,如果没有则重新加入,最后返回新数据
    def scratch_airport_name(scratch_url, old_airports):  
        new_airports = []  
        data = requests.get(scratch_url).text  
        all_airport_json = json.loads(data)['data']  
        for airport_by_word in all_airport_json.values():  
            for airport in airport_by_word:  
                if airport['fn'] not in old_airports:  
                    get_city_uri = get_city_url % airport['id']  
                    data2 = requests.get(get_city_uri).text  
                    soup = bs4.BeautifulSoup(data2, "html.parser")  
                    city = soup.find('span', text="城市").next_sibling.text  
                    new_airports.append(city + ',' + airport['fn'])  
        return new_airports  
    
     #main方法,执行这个py,默认调用main方法,相当于java的main
    if __name__ == '__main__':  
        MainUtil.main(resources_file_path, scratch_url, scratch_airport_name)
    

    scratch_flight_number.py:爬取全国航班号

    #!/usr/bin/python  
    # -*- coding: UTF-8 -*-  
    
    import requests  
    import bs4  
    import MainUtil  
    
    resources_file_path = '/resources/airplane/flightNameList.ini'  
    scratch_url = 'http://www.variflight.com/sitemap.html?AE71649A58c77='  
    
    
    def scratch_flight_number(scratch_url, old_flights):  
        new_flights = []  
        data = requests.get(scratch_url).text  
        soup = bs4.BeautifulSoup(data, "html.parser")  
        a_flights = soup.find('div', class_='list').find_all('a', recursive=False)  
        for flight in a_flights:  
            if flight.text not in old_flights and flight.text != '国内航段列表':  
                new_flights.append(flight.text)  
        return new_flights  
    
    
    if __name__ == '__main__':  
        MainUtil.main(resources_file_path, scratch_url, scratch_flight_number)
    

    scratch_movie_name.py:爬取最近上映的电影

    #!/usr/bin/python  
    # -*- coding: UTF-8 -*-  
    import re  
    import requests  
    import bs4  
    import json  
    import MainUtil  
    
    # 相对路径,也是需要将此路径存入数据库  
    resources_file_path = '/resources/movie/cinemaNameList.ini'  
    scratch_url = 'http://theater.mtime.com/China_Beijing/'  
    
    
    # scratch data with define url  
    def scratch_latest_movies(scratch_url, old_movies):  
        data = requests.get(scratch_url).text  
        soup = bs4.BeautifulSoup(data, "html.parser")  
        new_movies = []  
        new_movies_json = json.loads(  
            soup.find('script', text=re.compile("var hotplaySvList")).text.split("=")[1].replace(";", ""))  
        coming_movies_data = soup.find_all('li', class_='i_wantmovie')  
        # 上映的电影  
        for movie in new_movies_json:  
            move_name = movie['Title']  
            if move_name not in old_movies:  
                new_movies.append(movie['Title'])  
        # 即将上映的电影  
        for coming_movie in coming_movies_data:  
            coming_movie_name = coming_movie.h3.a.text  
            if coming_movie_name not in old_movies and coming_movie_name not in new_movies:  
                new_movies.append(coming_movie_name)  
        return new_movies  
    
    
    if __name__ == '__main__':  
        MainUtil.main(resources_file_path, scratch_url, scratch_latest_movies)
    

    scratch_train_number.py:爬取全国列车号

    #!/usr/bin/python  
    # -*- coding: UTF-8 -*-  
    import requests  
    import bs4  
    import json  
    import MainUtil  
    
    resources_file_path = '/resources/train/trainNameList.ini'  
    scratch_url = 'http://www.59178.com/checi/'  
    
    
    def scratch_train_number(scratch_url, old_trains):  
        new_trains = []  
        resp = requests.get(scratch_url)  
        data = resp.text.encode(resp.encoding).decode('gb2312')  
        soup = bs4.BeautifulSoup(data, "html.parser")  
        a_trains = soup.find('table').find_all('a')  
        for train in a_trains:  
            if train.text not in old_trains and train.text:  
                new_trains.append(train.text)  
        return new_trains  
    
    
    if __name__ == '__main__':  
        MainUtil.main(resources_file_path, scratch_url, scratch_train_number)
    

    scratch_train_station.py:爬取全国列车站

    #!/usr/bin/python  
    # -*- coding: UTF-8 -*-  
    import requests  
    import bs4  
    import random  
    import MainUtil  
    
    resources_file_path = '/resources/train/trainStationNameList.ini'  
    scratch_url = 'http://www.smskb.com/train/'  
    
    
    def scratch_train_station(scratch_url, old_stations):  
        new_stations = []  
        provinces_eng = (  
            "Anhui", "Beijing", "Chongqing", "Fujian", "Gansu", "Guangdong", "Guangxi", "Guizhou", "Hainan", "Hebei",  
            "Heilongjiang", "Henan", "Hubei", "Hunan", "Jiangsu", "Jiangxi", "Jilin", "Liaoning", "Ningxia", "Qinghai",  
            "Shandong", "Shanghai", "Shanxi", "Shanxisheng", "Sichuan", "Tianjin", "Neimenggu", "Xianggang", "Xinjiang",  
            "Xizang",  
            "Yunnan", "Zhejiang")  
        provinces_chi = (  
            "安徽", "北京", "重庆", "福建", "甘肃", "广东", "广西", "贵州", "海南", "河北",  
            "黑龙江", "河南", "湖北", "湖南", "江苏", "江西", "吉林", "辽宁", "宁夏", "青海",  
            "山东", "上海", "陕西", "山西", "四川", "天津", "内蒙古", "香港", "新疆", "西藏",  
            "云南", "浙江")  
        for i in range(0, provinces_eng.__len__(), 1):  
            cur_url = scratch_url + provinces_eng[i] + ".htm"  
            resp = requests.get(cur_url)  
            data = resp.text.encode(resp.encoding).decode('gbk')  
            soup = bs4.BeautifulSoup(data, "html.parser")  
            a_stations = soup.find('left').find('table').find_all('a')  
            for station in a_stations:  
                if station.text not in old_stations:  
                    new_stations.append(provinces_chi[i] + ',' + station.text)  
        return new_stations  
    
    
    if __name__ == '__main__':  
        MainUtil.main(resources_file_path, scratch_url, scratch_train_station)
    

    将项目放到测试服务器(centos7系统)中运行起来,我写了一个crontab,定时调用他们,下面贴出crontab。

    /etc/crontab

    SHELL=/bin/bash  
    PATH=/sbin:/bin:/usr/sbin:/usr/bin  
    MAILTO=root  
    
    # For details see man 4 crontabs  
    
    # Example of job definition:  
    # .---------------- minute (0 - 59)  
    # |  .------------- hour (0 - 23)  
    # |  |  .---------- day of month (1 - 31)  
    # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...  
    # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat  
    # |  |  |  |  |  
    # *  *  *  *  * user-name  command to be executed  
      0  0  *  *  * root python3 /data/app/smart/py/scratch_movie_name.py    >> /data/logs/smartpy/out.log 2>&1  
      0  1  *  *  1 root python3 /data/app/smart/py/scratch_train_station.py >> /data/logs/smartpy/out.log 2>&1  
      0  2  *  *  2 root python3 /data/app/smart/py/scratch_train_number.py  >> /data/logs/smartpy/out.log 2>&1  
      0  3  *  *  4 root python3 /data/app/smart/py/scratch_flight_number.py >> /data/logs/smartpy/out.log 2>&1  
      0  4  *  *  5 root python3 /data/app/smart/py/scratch_airport_name.py  >> /data/logs/smartpy/out.log 2>&1
    

    后续

    目前项目已经正常运行了三个多月啦。。。

    有问题反馈

    在阅读与学习中有任何问题,欢迎反馈给我,可以用以下联系方式跟我交流

    • 微信公众号:裸睡的猪
    • 在下面留言
    • 直接给我私信

    关于此公众号

    • 后期或提供各种软件的免费激活码
    • 推送python,java等编程技术文章和面试技巧
    • 当然你们可以将你们感兴趣的东西直接送给我
    • 谢谢你们真诚的关注,此公众号以后获得的收益将全部通过抽奖的形式送给大家
    • 以后如果博主要创业的话,也会在此公众号中挑选小伙伴哦~
    • 希望大家分享出去,让更多想学习python的朋友看到~

     

     

    展开全文
  • python爬虫bs4数据解析的本地文档源码
  • Python爬虫bs4库

    千次阅读 多人点赞 2017-03-22 08:48:11
    python爬虫常用库之bs4 bs4全名BeautifulSoup,是编写python爬虫常用库之一,主要用来解析html标签。 1.安装 pip install beautifulsoup4 或 python -m pip install beautifulsoup4 2.基本使用方法 bs4中最...

    python爬虫常用库之bs4


    bs4全名BeautifulSoup,是编写python爬虫常用库之一,主要用来解析html标签。


    1.安装

    pip install beautifulsoup4

    python -m pip install beautifulsoup4

    2.基本使用方法

    bs4中最基础的使用是BeautifulSoup类的使用,注意大小写哦。

    用BeautifulSoup来解析html:

    from bs4 import BeautifulSoup
    soup1 = BeautifulSoup("<html> A Html Text</html>", "html.parser")
    soup2 = BeautifulSoup(open("d://demo.html"), "html.parser")
    两个参数:第一个参数是要解析的html文本,第二个参数是使用那种解析器,对于HTML来讲就是html.parser,这个是bs4自带的解析器。 还可以安装lxml库来解析HTML或者XML,安装html5lib来解析html5lib。

    #lxml解析html(需pip install lxml)
    BeautifulSoup(html,'lxml')
    #lxml解析XML
    BeautifulSoup(xml,'xml')
    #html5lib解析(需安装: pip install html5lib)
    BeautifulSoup(html5,'html5lib')

    2.1 BeautifulSoup基本元素

    BeautifulSoup基本元素有:

    基本元素说明
    Tag标签,基本信息组织单元,用<>和</>标明开头和结尾
    Name标签的名字,<p>...</p>的名字就是’p',用法<>.name
    Attributes标签属性,字典形式,用法:<>.attrs['href']
    NavigableString标签内非属性字符串,<p>这是非属性字符串</p>,用法:<>.string
    Comment标签内的注释部分<p>显示的内容<!-- comment就是这里啦--></p>
    2.1.1 Tag标签

    任何存在于html语法中的标签都可以用soup.<tag>访问获得。

    当HTML文档中存在多个相同的tag时,soup.<tag>返回第一个

    >>> soup2 = BeautifulSoup("<p class=\"title\"><b>The Contents of b in first p</b></p><p class=\"course\">The second p</p>","html.parser")
    >>> soup2.p
    <p class="title"><b>The Contents of b in first p</b></p>

    2.1.2 Tag的name

    每个Tag都有自己的名字,通过<tag>.name获取,字符串类型

    >>> soup2.p.name
    'p'
    2.1.3 Tag的attrs(属性)

    一个Tag可以有0个或多个属性,字典类型。

    >>> soup2.p.attrs
    {'class': ['title']}
    >>> soup2.p.attrs['class']
    ['title']

    2.1.4 Tag的NavigableString

    NavigableString可以跨越多个层次的标签。

    >>> soup2.p
    <p class="title"><b>The Contents of b in first p</b></p>
    >>> soup2.p.string
    'The Contents of b in first p'
    >>> 

    2.1.5 Tag 的Comment

    Comment是一种特殊类型

    >>> soup3 = BeautifulSoup("<p>This is a NavigableString</p><b><!-- This is a Comment --></b>","html.parser")
    >>> soup3.p
    <p>This is a NavigableString</p>
    >>> soup3.b
    <b><!-- This is a Comment --></b>
    >>> soup3.p.string
    'This is a NavigableString'
    >>> type(soup3.p.string)
    <class 'bs4.element.NavigableString'>
    >>> soup3.b
    <b><!-- This is a Comment --></b>
    >>> soup3.b.string
    ' This is a Comment '
    >>> type(soup3.b.string)
    <class 'bs4.element.Comment'>
    >>> 


    <p class="title">....</p>
    p -> tag.name  'p'

    class="title" -> tag.attrs (字典列表)

    ... -> NavigableString OR Comment

    2.2 使用bs4遍历html内容

    HTML是个树状结构,<>...</>构成了从属关系。对HTML的遍历,有下行遍历,上行遍历和平行遍历三种遍历途径或方法。

    2.2.1 下行遍历

    属性说明
    .contents子节点的列表,将<tag>所有的儿子节点存入列表
    .children子节点的迭代类型,与.contents类似,主要用于循环遍历子节点
    .descendants子孙节点的迭代类型,包含所有子孙节点,用于循环遍历。

    BeautifulSoup类型是标签树的根节点。

    soup.head
    soup.head.contents
    soup.body.contents
    len(soup.body.contents)
    soup.body.contents[0]
    遍历子节点:
    for child in soup.body.children:
        print(child)
    遍历所有子孙节点:

    for child in soup.body.descendants:
        print(child)

    2.2.2 上行遍历

    属性说明
    .parent节点的父节点
    .parents节点的先辈节点标签的迭代类型,用于循环遍历先辈节点。

    >>> soup
    <html><head><title>This is a python demo page</title></head>
    <body>
    <p class="title"><b>The demo python introduces several python courses.</b></p>
    <p class="course">Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses:
    
    <a class="py1" href="http://www.icourse163.org/course/BIT-268001" id="link1">Basic Python</a> and <a class="py2" href="http://www.icourse163.org/course/BIT-1001870001" id="link2">Advanced Python</a>.</p>
    </body></html>
    >>> soup.title.parent
    <head><title>This is a python demo page</title></head>
    >>> soup.html.parent
    <html><head><title>This is a python demo page</title></head>
    <body>
    <p class="title"><b>The demo python introduces several python courses.</b></p>
    <p class="course">Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses:
    
    <a class="py1" href="http://www.icourse163.org/course/BIT-268001" id="link1">Basic Python</a> and <a class="py2" href="http://www.icourse163.org/course/BIT-1001870001" id="link2">Advanced Python</a>.</p>
    </body></html>
    >>> soup.parent
    >>> 
    注意:<html>..</html>标签的父节点是其自身

    而soup本身的父节点是空。

    进行先辈节点遍历时,包括soup自身,实际使用时需要判断。

    for parent in soup.a.parents:
    	if parent is None:
    		print(parent)
    	else:
    		print(parent.name)
    

    2.2.3 平行遍历

    属性说明
    .next_sibling返回按照HTML文本顺序的下一个平行节点标签
    .previous_sibling返回按照HTML文本顺序的上一个平行节点标签
    .next_siblings迭代类型,返回按照HTML文本顺序的后续所有平行节点标签
    .previous_siblings迭代类型,返回按照HTML文本顺序的前续所有平行节点标签
    平行遍历发生在同一个父节点下的各节点之间。

    soup.a.next_sibling
    soup.a.next_sibling.nextsibling
    soup.a.previous_sibling
    soup.a.parent

    遍历后续节点:

    for sibling in soup.a.next_siblings:
    	print(sibling)

    遍历前续节点:

    for sibling in previous_siblings:
    	print(sibling)

    3. 基于bs4库的HTML格式输出

    3.1 prettify()方法

    .prettify()为HTML文本<>及其内容增加‘\n'

    .prettify()可用于标签,方法<tag>.prettify()

    print(soup.a.prettify())

    3.2 bs4k库的编码

    bs4库将任何HTML输入都变成utf-8编码,python3.x 默认支持编码是utf-8。完美匹配!


    4.使用bs4进行HTML内容查找

    使用bs4进行HTML内容解析查找,基本方法是使用<>.find_all()来进行

    4.1 .find_all()的基本使用方法

    基本格式:

    <tag>.find_all(name, attrs, recursive, string, **kwargs)

    其返回值为一个列表,存储查找的结果

    参数:

    name -> 对标签名称的检索字符串,可以是个字符串列表,表达“或”关系

    soup.find_all('a')
    soup.find_all(['a','b'])
    soup.find_all(True)
    


    attrs -> 对标签属性值的检索字符串,可标注属性检索

    soup.find_all('a', 'title')
    soup.find_all(id='link1')
    soup.find_all(attrs = {"class":"course"})

    recursive -> 是否对子孙全部检索,默认True

    string -> <>...</>中的....的检索字符串

    soup.find_all(string = 'This is a sample')


    因为find_all太常用了,所以有简略用法:

    <tag>(...) <--> <tag>.find_all(...)

    soup(...) <--> soup.find_all(...)

    程序员果然都是懒人..........大笑

    4.2 扩展方法

    方法说明
    <>.find()搜索且只返回一个结果,同.find_all()参数
    <>.find_parents()在先辈节点中搜索,返回列表类型,同.find_all()参数
    <>.find_parent()在先辈节点中返回一个结果,同.find()参数
    <>.find_next_siblings()在后续平行节点中搜索,返回列表类型,同find_all()参数
    <>.find_next_sibling()在后续平行节点中搜索,返回一个结果,同find()参数
    <>.find_previous_siblings()在前续平行节点中搜索,返回列表类型,同find_all()参数
    <>.find_previous_sibling()在前续平行节点中搜索,返回一个结果,同find()参数

    展开全文
  • Python爬虫常用库总结:requests、beautifulsoup、selenium、xpath总结 文章目录 requests requests基础 requests模块发送get请求 response响应对象 response.text 和response.content的区别 解决中文乱码 response...

    Python爬虫常用库总结:requests、beautifulsoup、selenium、xpath总结

    在这里插入图片描述

    记得安装快速第三方库,Python经常需要安装第三方库,原始的下载速度很慢,使用国内的镜像就很快啦

    pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名
    

    快速下载模块

    官方网址:

    1. Requests: 让 HTTP 服务人类
    2. Beautiful Soup 4.4.0 文档
    3. Selenium官网
    4. lxml - XML and HTML with Python

    requests

    requests官方文档 https://docs.python-requests.org/zh_CN/latest/

    在这里插入图片描述

    进行爬虫,首先要对网址进行请求,这个时候就要用刀我们的requests模块了。requests是python的一个HTTP客户端库,跟urllib,urllib2类似。与urllib,urllib2相比,requests模块语法更加简单。正如他的官网所说:
    在这里插入图片描述

    requests模块介绍

    发送http请求,获取响应数据

    requests模块是一个第三方模块,需要在你的python(虚拟)环境中额外安装

    pip/pip3 install requests

    requests基础

    requests模块发送get请求

    #https://beishan.blog.csdn.net/
    import requests 
    # 目标url
    url = 'https://www.baidu.com' 
    # 向目标url发送get请求
    response = requests.get(url)
    # 打印响应内容
    print(response.text)
    

    response响应对象

    观察上边代码运行结果发现,有好多乱码;这是因为编解码使用的字符集不同早造成的;我们尝试使用下边的办法来解决中文乱码问题

    import requests 
    url = 'https://www.baidu.com' 
    # 向目标url发送get请求
    response = requests.get(url)
    # 打印响应内容
    # print(response.text)
    print(response.content.decode()) # 注意这里!
    
    1. response.text是requests模块按照chardet模块推测出的编码字符集进行解码的结果
    2. 网络传输的字符串都是bytes类型的,所以response.text = response.content.decode(‘推测出的编码字符集’)
    3. 我们可以在网页源码中搜索charset,尝试参考该编码字符集,注意存在不准确的情况

    response.text 和response.content的区别

    1. response.text
      • 类型:str
      • 解码类型: requests模块自动根据HTTP 头部对响应的编码作出有根据的推测,推测的文本编码
    2. response.content
      • 类型:bytes
      • 解码类型: 没有指定

    解决中文乱码

    通过对response.content进行decode,来解决中文乱码

    • response.content.decode() 默认utf-8
    • response.content.decode("GBK")
    • 常见的编码字符集
      • utf-8
      • gbk
      • gb2312
      • ascii (读音:阿斯克码)
      • iso-8859-1

    response响应对象的其它常用属性或方法

    #https://beishan.blog.csdn.net/
    # 1.2.3-response其它常用属性
    import requests
    
    # 目标url
    url = 'https://www.baidu.com'
    
    # 向目标url发送get请求
    response = requests.get(url)
    
    # 打印响应内容
    # print(response.text)
    # print(response.content.decode()) 			# 注意这里!
    print(response.url)							# 打印响应的url
    print(response.status_code)					# 打印响应的状态码
    print(response.request.headers)				# 打印响应对象的请求头
    print(response.headers)						# 打印响应头
    print(response.request._cookies)			# 打印请求携带的cookies
    print(response.cookies)						# 打印响应中携带的cookies
    

    requests实操

    requests模块发送请求

    发送带header的请求

    我们先写一个获取百度首页的代码

    import requests
    url = 'https://www.baidu.com'
    response = requests.get(url)
    print(response.content.decode())
    # 打印响应对应请求的请求头信息
    print(response.request.headers)
    

    从浏览器中复制User-Agent,构造headers字典;完成下面的代码后,运行代码查看结果

    import requests
    
    url = 'https://www.baidu.com'
    
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
    
    # 在请求头中带上User-Agent,模拟浏览器发送请求
    response = requests.get(url, headers=headers) 
    
    print(response.content)
    
    # 打印请求头信息
    print(response.request.headers)
    

    发送带参数的请求

    我们在使用百度搜索的时候经常发现url地址中会有一个 ?,那么该问号后边的就是请求参数,又叫做查询字符串

    在url携带参数,直接对含有参数的url发起请求

    import requests
    
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
    
    url = 'https://www.baidu.com/s?wd=python'
    
    response = requests.get(url, headers=headers)
    
    

    通过params携带参数字典

    ​ 1.构建请求参数字典

    ​ 2.向接口发送请求的时候带上参数字典,参数字典设置给params

    import requests
    
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
    
    # 这是目标url
    # url = 'https://www.baidu.com/s?wd=python'
    
    # 最后有没有问号结果都一样
    url = 'https://www.baidu.com/s?'
    
    # 请求参数是一个字典 即wd=python
    kw = {'wd': 'python'}
    
    # 带上请求参数发起请求,获取响应
    response = requests.get(url, headers=headers, params=kw)
    
    print(response.content)
    
    • 从浏览器中复制User-Agent和Cookie
    • 浏览器中的请求头字段和值与headers参数中必须一致
    • headers请求参数字典中的Cookie键对应的值是字符串
    import requests
    
    url = 'https://github.com/USER_NAME'
    
    # 构造请求头字典
    headers = {
        # 从浏览器中复制过来的User-Agent
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36',
        # 从浏览器中复制过来的Cookie
        'Cookie': 'xxx这里是复制过来的cookie字符串'
    }
    
    # 请求头参数字典中携带cookie字符串
    resp = requests.get(url, headers=headers)
    
    print(resp.text)
    

    超时参数timeout的使用

    在平时网上冲浪的过程中,我们经常会遇到网络波动,这个时候,一个请求等了很久可能任然没有结果。

    在爬虫中,一个请求很久没有结果,就会让整个项目的效率变得非常低,这个时候我们就需要对请求进行强制要求,让他必须在特定的时间内返回结果,否则就报错。

    1. 超时参数timeout的使用方法

      response = requests.get(url, timeout=3)

    2. timeout=3表示:发送请求后,3秒钟内返回响应,否则就抛出异常

    import requests
    
    
    url = 'https://twitter.com'
    response = requests.get(url, timeout=3)     # 设置超时时间
    
    

    requests发送post请求的方法

    • response = requests.post(url, data)

    • data参数接收一个字典

    • requests模块发送post请求函数的其它参数和发送get请求的参数完全一致

    BeautifulSoup

    BeautifulSoup官方文档 https://beautifulsoup.readthedocs.io/zh_CN/v4.4.0/

    Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间.

    在这里插入图片描述

    常见解释器的优缺点

    在这里插入图片描述

    常用操作

    安装方法

    pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple beautifulsoup4  
    

    导入即可

    from bs4 import BeautifulSoup
    
    html_doc = """
    <html><head><title>The Dormouse's story</title></head>
    <body>
    <p class="title"><b>The Dormouse's story</b></p>
    
    <p class="story">Once upon a time there were three little sisters; and their names were
    <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
    <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
    <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
    and they lived at the bottom of a well.</p>
    
    <p class="story">...</p>
    """
    
    soup = BeautifulSoup(html_doc,"lxml")
    

    几个简单的浏览结构化数据的方法

    soup.title
    
    <title>The Dormouse's story</title>
    
    soup.title.name
    
    'title'
    
    soup.title.string
    
    "The Dormouse's story"
    
    soup.title.text
    
    "The Dormouse's story"
    
    soup.title.parent.name
    
    'head'
    
    soup.p
    
    <p class="title"><b>The Dormouse's story</b></p>
    
    soup.p.name
    
    'p'
    
    soup.p["class"]
    
    ['title']
    
    soup.a
    
    <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
    
    soup.find("a")
    
    <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
    
    soup.find_all("a")
    
    [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
     <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
     <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    

    从文档中找到所有的< a>标签的链接

    for link in soup.find_all("a"):
        print(link.get("href"))
    
    http://example.com/elsie
    http://example.com/lacie
    http://example.com/tillie
    

    在文档中获取所有的文字内容

    print(soup.get_text())
    
    The Dormouse's story
    
    The Dormouse's story
    Once upon a time there were three little sisters; and their names were
    Elsie,
    Lacie and
    Tillie;
    and they lived at the bottom of a well.
    ...
    

    通过标签和属性获取

    • Tag有很多方法和属性,在 遍历文档树 和 搜索文档树 中有详细解释.现在介绍一下tag中最重要的属性: name和attributes
    soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
    tag  = soup.b
    tag
    
    <b class="boldest">Extremely bold</b>
    
    type(tag)
    
    bs4.element.Tag
    

    Name属性

    • 每个tag都有自己的名字,通过 .name 来获取:
    tag.name
    
    'b'
    
    • 如果改变了tag的name,那将影响所有通过当前Beautiful Soup对象生成的HTML文档
    tag.name = "blockquote"
    tag
    
    <blockquote class="boldest">Extremely bold</blockquote>
    

    多个属性

    • 一个tag可能有很多个属性.tag 有一个 “class” 的属性,值为 “boldest” . tag的属性的操作方法与字典相同:
    tag["class"]
    
    ['boldest']
    
    tag.attrs
    
    {'class': ['boldest']}
    
    • tag的属性可以被添加,删除或修改. 再说一次, tag的属性操作方法与字典一样
    tag["class"] = "verybold"
    tag["id"] = 1
    tag
    
    <blockquote class="verybold" id="1">Extremely bold</blockquote>
    
    del tag["class"]
    tag
    
    <blockquote id="1">Extremely bold</blockquote>
    

    多值属性

    css_soup = BeautifulSoup('<p class="body strikeout"></p>')
    css_soup.p['class']
    
    ['body', 'strikeout']
    
    css_soup = BeautifulSoup('<p class="body"></p>')
    css_soup.p['class']
    
    ['body']
    

    可以遍历的字符串

    1. 字符串常被包含在tag内.Beautiful Soup用 NavigableString 类来包装tag中的字符串:
    tag.string
    
    'Extremely bold'
    
    type(tag.string)
    
    bs4.element.NavigableString
    
    1. 一个 NavigableString 字符串与Python中的Unicode字符串相同,
      并且还支持包含在遍历文档树 和 搜索文档树 中的一些特性.
      通过 unicode() 方法可以直接将 NavigableString 对象转换成Unicode字符串:

    2. tag中包含的字符串不能编辑,但是可以被替换成其他的字符串,用replace_with()方法

    tag.string.replace_with("No longer bold")
    tag
    
    <blockquote id="1">No longer bold</blockquote>
    

    注释及特殊字符串

    1. 文档的注释部分
    markup = "<b><!--Hey, buddy. Want to buy a used parser?--></b>"
    soup = BeautifulSoup(markup)
    comment = soup.b.string
    comment
    
    'Hey, buddy. Want to buy a used parser?'
    
    type(comment)
    
    bs4.element.Comment
    
    1. Comment 对象是一个特殊类型的 NavigableString 对象:
    comment
    
    'Hey, buddy. Want to buy a used parser?'
    

    但是当它出现在HTML文档中时, Comment 对象会使用特殊的格式输出:

    print(soup.prettify())
    
    <html>
     <body>
      <b>
       <!--Hey, buddy. Want to buy a used parser?-->
      </b>
     </body>
    </html>
    
    from bs4 import CData
    cdata = CData("A CDATA block")
    comment.replace_with(cdata)
    print(soup.b.prettify())
    
    <b>
     <![CDATA[A CDATA block]]>
    </b>
    

    遍历文档树

    html_doc = """
    <html><head><title>The Dormouse's story</title></head>
        <body>
    <p class="title"><b>The Dormouse's story</b></p>
    
    <p class="story">Once upon a time there were three little sisters; and their names were
    <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
    <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
    <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
    and they lived at the bottom of a well.</p>
    
    <p class="story">...</p>
    """
    
    from bs4 import BeautifulSoup
    
    soup = BeautifulSoup(html_doc,"html.parser")
    

    子节点

    一个Tag可能包含多个字符串或其它的Tag,这些都是这个Tag的子节点.Beautiful Soup提供了许多操作和遍历子节点的属性.

    soup.head
    
    <head><title>The Dormouse's story</title></head>
    
    soup.title
    
    <title>The Dormouse's story</title>
    

    这是个获取tag的小窍门,可以在文档树的tag中多次调用这个方法.下面的代码可以获取标签中的第一个标签:

    soup.body.b
    
    <b>The Dormouse's story</b>
    

    通过点取属性的方式只能获得当前名字的第一个tag:

    soup.a
    
    <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
    

    find_all方法

    如果想要得到所有的标签,或是通过名字得到比一个tag更多的内容的时候,就需要用到 Searching the tree 中描述的方法,比如: find_all()

    soup.find_all("a")
    
    [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
     <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
     <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    

    .contents和.children

    head_tag = soup.head
    head_tag
    
    <head><title>The Dormouse's story</title></head>
    
    head_tag.contents
    
    [<title>The Dormouse's story</title>]
    
    head_tag.contents[0]
    
    <title>The Dormouse's story</title>
    
    head_tag.contents[0].contents
    
    ["The Dormouse's story"]
    

    selenium

    在这里插入图片描述

    selenium官方文档 https://www.selenium.dev/selenium/docs/api/py/api.html

    selenium介绍

    chrome浏览器的运行效果

    在下载好chromedriver以及安装好selenium模块后,执行下列代码并观察运行的过程

    from selenium import webdriver 
    
    # 如果driver没有添加到了环境变量,则需要将driver的绝对路径赋值给executable_path参数
    # driver = webdriver.Chrome(executable_path='/home/worker/Desktop/driver/chromedriver')
    
    # 如果driver添加了环境变量则不需要设置executable_path
    driver = webdriver.Chrome()
    
    # 向一个url发起请求
    driver.get("http://www.itcast.cn/")
    
    # 把网页保存为图片,69版本以上的谷歌浏览器将无法使用截图功能
    # driver.save_screenshot("itcast.png")
    
    print(driver.title) # 打印页面的标题
    
    # 退出模拟浏览器
    driver.quit() # 一定要退出!不退出会有残留进程!
    

    phantomjs无界面浏览器的运行效果

    PhantomJS 是一个基于Webkit的“无界面”(headless)浏览器,它会把网站加载到内存并执行页面上的 JavaScript。下载地址:http://phantomjs.org/download.html

    from selenium import webdriver 
    
    # 指定driver的绝对路径
    driver = webdriver.PhantomJS(executable_path='/home/worker/Desktop/driver/phantomjs') 
    # driver = webdriver.Chrome(executable_path='/home/worker/Desktop/driver/chromedriver')
    
    # 向一个url发起请求
    driver.get("http://www.itcast.cn/")
    
    # 把网页保存为图片
    driver.save_screenshot("itcast.png")
    
    # 退出模拟浏览器
    driver.quit() # 一定要退出!不退出会有残留进程!
    

    无头浏览器与有头浏览器的使用场景

    • 通常在开发过程中我们需要查看运行过程中的各种情况所以通常使用有头浏览器
    • 在项目完成进行部署的时候,通常平台采用的系统都是服务器版的操作系统,服务器版的操作系统必须使用无头浏览器才能正常运行

    selenium的作用和工作原理

    利用浏览器原生的API,封装成一套更加面向对象的Selenium WebDriver API,直接操作浏览器页面里的元素,甚至操作浏览器本身(截屏,窗口大小,启动,关闭,安装插件,配置证书之类的)

    selenium的安装以及简单使用

    以edge浏览器为例 参见这个blog哦,驱动chrome浏览器同理
    selenium驱动edge浏览器

    • chromedriver环境的配置
      • windows环境下需要将 chromedriver.exe 所在的目录设置为path环境变量中的路径
      • linux/mac环境下,将 chromedriver 所在的目录设置到系统的PATH环境值中

    selenium的简单使用

    接下来我们就通过代码来模拟百度搜索

    import time
    from selenium import webdriver
    
    # 通过指定chromedriver的路径来实例化driver对象,chromedriver放在当前目录。
    # driver = webdriver.Chrome(executable_path='./chromedriver')
    # chromedriver已经添加环境变量
    driver = webdriver.Chrome()
    
    # 控制浏览器访问url地址
    driver.get("https://www.baidu.com/")
    
    # 在百度搜索框中搜索'python'
    driver.find_element_by_id('kw').send_keys('python')
    # 点击'百度搜索'
    driver.find_element_by_id('su').click()
    
    time.sleep(6)
    # 退出浏览器
    driver.quit()
    
    • webdriver.Chrome(executable_path='./chromedriver')中executable参数指定的是下载好的chromedriver文件的路径
    • driver.find_element_by_id('kw').send_keys('python')定位id属性值是’kw’的标签,并向其中输入字符串’python’
    • driver.find_element_by_id('su').click()定位id属性值是su的标签,并点击
      • click函数作用是:触发标签的js的click事件

    值是’kw’的标签,并向其中输入字符串’python’

    • driver.find_element_by_id('su').click()定位id属性值是su的标签,并点击
    • click函数作用是:触发标签的js的click事件

    使用xpath来提取数据,爬取数据的简单语法。

    lxml

    在这里插入图片描述

    requests官方文档 https://lxml.de/

    pip install lxml
    
    • 导入模块
    from lxml import etree
    
    • 利用xpath获取text或者href内容
    /li/a/@href 这样取的应该是href的内容
    /li/a/text() 这样取得是text内容
    

    etree的使用

    h=etree.HTML(response.text)#response.text是网页的源码
    h.xpath('//img')  #寻找所有的img结点,
    h.xpath('//div').xpath('.//img')#寻找所有div下的所有img结点
    

    xpath的语法

    符号
    XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。

    表达式描述
    /从根节点选取
    //从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
    .选取当前节点。
    . .选取当前节点的父节点。
    @选取属性。
    |在两个中结点中选择
    ()用()来包含|
    *包含所有元素
    not取反

    实例

    路径表达式结果
    bookstore选取 bookstore 元素的所有子节点。
    /bookstore选取根元素 bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!
    bookstore/book选取属于 bookstore 的子元素的所有 book 元素。
    //book选取所有 book 子元素,而不管它们在文档中的位置。
    bookstore//book选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。
    //@lang选取名为 lang 的所有属性。
    //*[@class]选取带有class属性的所有元素
    //div[@*]匹配任意属性的div元素
    //a[not(@class)]匹配没有class属性的a元素

    谓语
    带谓语的路径表达式

    路径表达式结果
    /bookstore/book[1]选取属于 bookstore 子元素的第一个 book 元素。
    /bookstore/book[last()]选取属于 bookstore 子元素的最后一个 book 元素。
    /bookstore/book[last()-1]选取属于 bookstore 子元素的倒数第二个 book 元素。
    /bookstore/book[position()< 3]选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
    //title[@lang]选取所有拥有名为 lang 的属性的 title 元素。
    //title[@lang=‘eng’]选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。
    /bookstore/book[price>35.00]选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。
    /bookstore/book[price>35.00]/title选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。

    在这里插入图片描述

    到这里就结束了,如果对你有帮助你。当然学无止境,这些只是爬虫的基础,更多姿势需要你自己去探索呦。https://beishan.blog.csdn.net/

    1. Tableau数据分析-Chapter01条形图、堆积图、直方图
    2. Tableau数据分析-Chapter02数据预处理、折线图、饼图
    3. Tableau数据分析-Chapter03基本表、树状图、气泡图、词云
    4. Tableau数据分析-Chapter04标靶图、甘特图、瀑布图
    5. Tableau数据分析-Chapter05数据集合并、符号地图
    6. Tableau数据分析-Chapter06填充地图、多维地图、混合地图
    7. Tableau数据分析-Chapter07多边形地图、背景地图
    8. Tableau数据分析-Chapter08数据分层、数据分组、数据集
    9. Tableau数据分析-Chapter09粒度、聚合与比率
    10. Tableau数据分析-Chapter10 人口金字塔、漏斗图、箱线图
    11. Tableau数据分析-Chapter11 范围-线图、倾斜图
    12. Tableau数据分析-Chapter12 网络图、弧线图
    13. Tableau数据分析-Chapter13雷达图、凹凸图
    14. Tableau数据分析-Chapter14线性回归、时间序列分析
    展开全文
  • python爬虫学习笔记 2.9 (使用bs4得案例) python爬虫学习笔记 1.1(通用爬虫和聚焦爬虫) python爬虫学习笔记 1.2 ( HTTP和HTTPS ) python爬虫学习笔记 1.3 str和bytes的区别 python爬虫学习笔记 1.4 (Request...
  • 简单python爬虫BS4框架介绍及简单示例: 总所周知python有着比较好的对于数据的的“亲和力”,是数据科学家十分喜爱的编程语言,其内置了许多其他的库,使操作起来有着诸多的便捷。python对于数据的获取上,比如...

    简单python爬虫之BS4框架介绍及简单示例:

    侵权或其他原因请联系删除 修改


    总所周知python有着比较好的对于数据的的“亲和力”,是数据科学家十分喜爱的编程语言,其内置了许多其他的库,使操作起来有着诸多的便捷。python对于数据的获取上,比如说,在网络爬虫的传统应用领域,即对于数据的抓取等方面有着许多的先天优势。目前,比较流行的爬虫框架Scrapy,HTTP工具包urlib2,HTML解析工具beautifulsoup,XML解析器lxml,等等,都是能够独当一面的Python类库。在这里,我们简单介绍一下这其中的HTML解析工具beautifulsoup库。

    首先,介绍beautifulsoup(之后均简称为BS4)的原因是,作为爬虫入门级的框架之一,它上手快捷,语句简单,思路好懂,实乃既是爬虫初学又想很快看到一些实际效果的小伙伴学习使用的必学利器。其次,介绍BS4是由于在上个小项目中实际运用到的爬虫框架,而且实际获取到了数据,比较方便展示以及理解,所以选择了这个来做一些讲解。

    简介:Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库,提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。

    就我个人理解来说,使用BS4就是首先,你需要告诉计算机你需要从哪个网站去获取信息(在这里需要注意,许多的网站都有反爬机制以及一些协议上的问题,这些问题的解决需要更加深度的了解以及学习,而且呢,这种东西一定是办法比困难多,只要多去了解方法一定可以获得你想获得的信息,这里示例是爬取的贝壳租房网,我们可以很简单的获取房屋信息来使用),然后根据所获取到的东西,将之做成一锅“汤”,然后呢,你想要什么东西,直接从汤里边“舀”就可以了。当然具体如何实现,由下边的代码及部分示例来看:

    项目要求:获取到房源的朝向,大小,租金,名字,租赁方式及厅室情况等相关信息

    import bs4
    import requests
    data = requests.get('https://bj.zu.ke.com/zufang', timeout=300)
    soup = bs4.BeautifulSoup(data.text, "html.parser")
    

    图示代码将网址“https://bj.zu.ke.com/zufang”的内容获取到,包括网页源码中的全部信息(具体内容可以根据各自浏览器,使用右键单击页面的“检查”或者“查看网页源代码”看到),赋给代码中的data变量中,然后通过代码 soup = bs4.BeautifulSoup(data.text, “html.parser”) 将data中信息使用 html.parser 模块处理后放到 soup中,也就是之前说过的做一锅“汤”(soup,英文“汤”)(html.parser 模块具体功能参考https://baijiahao.baidu.com/s?id=1637614366297669334&wfr=spider&for=pc 的文章,这里不做讲解)。

    之后,BS4中支持将某个标签下的东西获取到,我们从实例中来看:

    HouseInformation = soup.find_all("div", class_="content__list--item")   # 进入新房的信息
    CityInformation = soup.find_all("p", class_="content__list--item--des")   # 新房的相关信息
    

    首先,我们在获得信息之后,由于我们不是需要全部的信息,所以,我们通常会设置一定条件,或者从一定范围内获取信息。在这里,我们要从获得的一整篇东西里边获取的文本里边获得具体想要的东西,就会用到之前说过的标签了。我们在通过网页的检查源代码可以看到每一个房屋信息都在该标签树下:
    "<div class=”content__list–item” " …如图(方框):
    而更加细致的也是我们需求的房屋所在地区,大小,朝向,室厅卫的信息是在该条目下的
    "p class=”content__list–item–des”> "中 如图(方框):
    在这里插入图片描述
    当然,此时如果打印出这些信息后观察会发现你通过代码获得的就是图样中的一行行信息。
    此时,我们使用HouseInformation,CityInformation两个变量将该页面中的所有类似信息通过上述代码获取承接到,由于数量不止一个,所以所有获取会变为一个类型为’bs4.element.ResultSet’的变量,可以使用类似列表下标的方法来调用其中的某条来进行操作。
    接下来呢,我们便可以使用正则表达式的方式,在自己转化为字符串的HouseInformation[i]中获取相关信息了,需要观察这些字符串的特点之后,按照一定的规律以及正则表达式的规则来获取相关信息,此处以以下几项为例:

    for i in range(len(HouseInformation)):
        Data = str(HouseInformation[i])
        ID = re.findall(".*zufang/(.*).html", Data)  # 房源标号
        HouseType = re.findall(".*(.室)(.厅)(.卫)", Data)  # 规格
        HouseTheme = re.findall(".*>\n\s*(.*)</a>", Data)  # 房屋主题
        District = re.findall("\">(.*?)<", str(CityInformation[i]))  # 所处地区
        if len(District)==3:
            f.write(str0 + District[0] + " " + District[1] + " " + District[2]+" ")
        else:
            f.write(str0 + "NULL NULL NULL ")
        f.write(HouseTheme[1] + " ")
    if (HouseType):
        f.write(HouseType[0][0] + " " + HouseType[0][1] + " " + HouseType[0][2] + " ")
    else:
        f.write("NULL" + " " + "NULL" + " " + "NULL" + " ")
    f.write("\n")
    

    那在这段代码中我们使用的操作是一定的正则表达式以及一些判断操作,以及无数据是填入“NULL”以保证数据的整齐性。所获取的写入文件,方便我们之后进行处理,文件内容如下:
    在这里插入图片描述
    总长度30条,为一个页面的房屋数量。至此,我们已经可以发现,我们已经将爬到的信息进行了简单的整理处理后放入了文件中,方便我们之后的数据处理以及记录分析,框架使用及简单实例完成。

    小结:我们在使用BS4时,步骤几乎都是构建网站链接(字符串类型)-> 获取信息 -> 观察相关信息所在标签 -> 获取标签内信息 -> 处理为我们所需要的信息,而在实例中,我们并没有使用更深入的东西,感兴趣的话可以再自己寻找资源去了解学习。 目前自己在学习另一个爬虫框架Scripy,做出一定小成果后会继续分享出来。

    由于使用了其他商业网站资源,如有问题请联系我删除相关内容,本人只是自己练习使用,未用作其他用途。

    展开全文
  • python爬虫bs4模块一、bs4简介二、使用方法三、BeautifulSoup四大对象种类(1)tag(2)NavigableString(3)BeautifulSoup(4)Comment四、CSS选择器 一、bs4简介 即BeautifulSoup,是python种的一个库,最主要的...
  • python爬虫入门教程(二):开始一个简单的爬虫

    万次阅读 多人点赞 2017-09-12 15:02:21
    python爬虫入门教程,介绍编写一个简单爬虫的过程。
  • python爬虫基础入门】系列是对python爬虫的一个入门练习实践,旨在用最浅显易懂的语言,总结最明了,最适合自己的方法,本人一直坚信,总结才会使人提高 文章目录1. BeautifulSoup库简介2. BeautifulSoup库的主要...
  • python爬虫bs4的基本使用

    千次阅读 多人点赞 2019-06-17 21:22:07
    import requests from bs4 import BeautifulSoup # 创建BeautifulSoup对象 # 当数据来源为本地文件时 file = open("xxx.html") soup = BeautifulSoup(file, "lxml") # 当数据来源为网络时 content =...
  • 我的第一个Python爬虫——谈心得

    万次阅读 多人点赞 2018-03-30 19:24:26
    相信各大高校应该都有本校APP或超级课程表之类的软件,在信息化的时代能快速收集/查询自己想要的咨询也是种很重要的能力,所以记下了这篇博客,用于总结我所学到的东西,以及用于记录我的第一个爬虫的初生。...
  • Python 爬虫系列教程一爬取批量百度图片

    万次阅读 多人点赞 2018-07-29 19:40:05
    很久之前就学习了Python的爬虫了,也用来做过一些项目(主要是一些课程项目),但时间比较紧,一直没有空把它写下来,这个暑假,我可能会逐渐更新Python爬虫的相关知识。 项目1:实现批量爬取百度图片 先简单的...
  • python爬虫python爬虫demo

    千次阅读 2018-02-21 11:29:07
    我在入门python爬虫的时候,在网上找demo,找了好久都找不到,好不容易找到了一个,但是又跑不起来。 我把一个简易的demo贴出来。 使用 BeautifulSoup 库 抓取 酷狗音乐TOP500 第1页到第9页的音乐歌名、歌手、时...
  • Python爬虫bs4数据解析select方法

    千次阅读 2020-07-18 09:17:03
    from bs4 import BeautifulSoup soup.select('.class名称') 2.通过ID查找 soup.select('#id名称') 3.通过标签名查找 soup.select('标签名') 4.层级查找 soup.select('.tang > ul > li > a') # 中间如果...
  • 全网最全python爬虫精进

    万次阅读 多人点赞 2021-04-25 17:00:23
    第0关 认识爬虫 ** 1、初始爬虫 爬虫,从本质上来说,就是利用程序在网上拿到对我们有价值的数据。 2、明晰路径 2-1、浏览器工作原理 (1)解析数据:当服务器把数据响应给浏览器之后,浏览器并不会直接把数据丢给...
  • PYTHON爬虫

    千次阅读 多人点赞 2020-03-22 10:52:06
    PYTHON爬虫爬虫的概念通用爬虫原理聚焦爬虫——根据特定的需求,抓取指定的数据爬取步骤开发环境课程内容 爬虫的概念 爬虫可分为: 通用爬虫:百度、360、搜狐、谷歌、必应… 聚焦爬虫: 通用爬虫原理 抓取网页 ...
  • python爬虫教程:bs4的使用

    千次阅读 2019-04-12 20:21:03
    bs4 的使用 bs4 就是Beautiful Soup 的简称,这是一个工具箱,通过解析文档为用户提供需要抓取的数据, 使用这个不需要在编码的上面考虑,他会自动转换为utf-8编码。 但是使用这个的前提的就是网页是完整的,但是...
  • python爬虫是什么意思python爬虫即网络爬虫,网络爬虫是一种程序,主要用于搜索引擎,它将一个网站的所有内容与链接进行阅读,并建立相关的全文索引到数据库中,然后跳到另一个网站.样子好像一只大蜘蛛.当人们在网络...
  • 使用python爬虫库requests,urllib爬取今日头条街拍美图 代码均有注释 import re,json,requests,os from hashlib import md5 from urllib.parse import urlencode from requests.exceptions import ...
  • getCommentInfo.py:from bs4 import BeautifulSoupimport requests from mylog import MyLog as mylog # 《Python 网络爬虫实战》胡松涛著 P196class Item(): title = None firstAuthor = None firstTime = None
  • python爬虫基于bs4的查找select和find

    千次阅读 2020-10-04 15:31:39
    最近在学习爬虫的时候,发现之前学的总是会忘记,虽然在网上保存了查询的资料的书签,但是感觉还是不够直观,总还是需要再在网上查询,所以,现在打算在CSND上写一下平时的一些笔记,很多应该会从查到的资料粘贴过来...
  • python爬虫.png

    2020-07-15 09:13:50
    由本人整理的mooc精品课程嵩天老师的python爬虫课程,以一图流的思维导图形式展开,方便学习和使用
  • 本人用的python3.7,代码在anacoda 3.7版 和自装的bs4 4.9.1都成功测试。 初学爬虫,结果第一个BeautifulSoup的实例就运行失败,print(bs,h1)返回None,但原网页明明就有h1标签。 比如下面的代码。 from bs4 ...
  • Python 爬虫 xpath 和 bs4

    2018-07-01 00:14:05
    <a href="https://blog.csdn.net/Yellow_python">B </body>''' from lxml import etree # 创建【Element】对象 element = etree.HTML(html, etree.HTMLParser()) # xpath 提取信息,返回列表 text = ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 33,529
精华内容 13,411
关键字:

python爬虫bs

python 订阅
爬虫 订阅