美文网首页
数据采集-爬虫实战

数据采集-爬虫实战

作者: CoderInsight | 来源:发表于2023-02-14 09:17 被阅读0次

    6.爬虫实战:豆瓣图书Top250 爬取

    本实验爬取网页网址为 豆瓣图书Top250页面

    爬取的信息为图书名称、图书链接、评分、评价人数和一句话点评。

    (1).Xpath处理失败的方法

    按照上一实验的方法,对书名单击右键-检查,在弹出的窗口中再次单击右键-Copy-Copy Xpath复制书名的Xpath:
    //*[@id="content"]/div/div[1]/div/table[1]/tbody/tr/td[2]/div[1]/a

    # 导入requests模块和bs4模块
    import requests
    from lxml import etree
    
    # 引入要爬取的网页的url
    url = 'https://book.douban.com/top250'
    # 加入请求头,防止网站监测出来我们是爬虫,所以都必须要引入请求;对于有需要 登录 的页面需要加上cookices,那么直接在header字典中将 " 'Cookie': '你的cookie' "添加进去
    header={
       "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36"
    }
    # 1、获取网页的响应
    # url,请求头,设置访问超时时间
    response = requests.get(url, headers=header,timeout=30)
    # 2,当网页获取成功的之后,设置网页的编码格式,方式出现中文的乱码
    response.encoding='utf-8'
    
    # 3,从获取到的文本连接中获取对应的网页源代码字符串
    data = response.text
    
    # 4.对获取到的网页源代码字符串使用etree解析
    s=etree.HTML(data)
    
    # 5.直接请求对应 书名 的Xpath
    file=s.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tbody/tr/td[2]/div[1]/a')
    
    ####  此时会报错,读取不到指定的Xpath的值,返回空值  ####
    
    # 这里需要注意,浏览器复制的xpath信息并不是完全可靠的,浏览器经常会自己在里面增加多余的tbody标签,我们需要手动把这些标签删掉。
    
    # 5.直接请求对应 书名 的Xpath(此时返回的是一个对象)
    file=s.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div[1]/a')
    
    # 6.当我们要获取其中的值的时候,我们是不仅需要删除多余的tbody,还要拼接 "/text()" 来获取值
    file=s.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div[1]/a/text()')
    print(file)
    # 输出结果:['\n                红楼梦\n\n                \n              ']
    

    (2),爬取整本书的信息

    1, 我们将整本书和书名的xpath进行对比
    2, 不难发现,书名和评分 xpath 的前半部分和整本书的 xpath 一致的,那我们可以通过这样写 xpath 的方式来定位信息:

    //*[@id=“content”]/div/div[1]/div/table[1]                          # 整本书
    //*[@id=“content”]/div/div[1]/div/table[1]/tr/td[2]/div[1]/a        # 书名
    //*[@id=“content”]/div/div[1]/div/table[1]/tr/td[2]/div[2]/span[2]  # 评分 
    
    book = s.xpath("//*[@id='content']/div/div[1]/div/table[1]")
    for div in book:
        # 对于标签的属性 例如: title 就直接使用 @title 的方式进行获取;href 就直接使用 @href 的方式进行获取
        title =div.xpath("./tr/td[2]/div[1]/a/@title")
        href =div.xpath("./tr/td[2]/div[1]/a/@href")
        # 对于标签中的文本就直接使用text()的方式进行获取
        score=div.xpath("./tr/td[2]/div[2]/span[2]/text()")
        # 输出语句可以使用 .format 的格式化方式(类似于C语言)输出
        print("{}: {}, {}".format(title, score, href))
        # 列表的取值直接使用下标的方式进行列表值的获取
        print("{}: {}, {}".format(title[0], score[0], href[0]))
    

    (3).爬取当前页中的所有的书籍信息

    books=s.xpath("//*[@id='content']/div/div[1]/div/table")
    for div in books:
        title = div.xpath("./tr/td[2]/div[1]/a/@title")[0]
        score=div.xpath("./tr/td[2]/div[2]/span[2]/text()")[0]
        print("{}: {}".format(title,score))
    

    (4).爬取多个网页的书籍信息

    1,首先分析翻页之后的 url 是如何变化的:

    https://book.douban.com/top250?start=0   # 第一页
    https://book.douban.com/top250?start=25   # 第二页
    https://book.douban.com/top250?start=50   # 第三页 
    

    2,得到 url 变化的规律很简单,只是 start=() 的数字不一样而已,而且是以每页25为单位,递增25。于是爬取多页网页只需要写一个循环:

    # 爬取前十页中的信息
    for a in range(10):
        # 总共10个页面,用 a*25 保证以25为单位递增
      url = 'https://book.douban.com/top250?start={}'.format(a*25)    
    

    3,range() 函数简介

    基本语法:range(start, stop, step)

    start:计数从 start 开始。默认是从 0 开始。例如 range(5) 等价于range(0,5);

    end:计数到 end 结束,但不包括 end。例如:range(0,5)是 [0,1,2,3,4] 没有5

    step:步长,默认为1。例如:range(0,5) 等价于 range(0,5,1)

    >>> range(10)         #从 0 开始到 10 (不包含)
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
    >>> range(1, 11)      #从 1 开始到 11 (不包含)
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
    >>> range(0, 30, 5)   #从0到30(不包含),步长为5 
    [0, 5, 10, 15, 20, 25]
    
    # 完整代码
    # 导入requests模块和bs4模块
    import requests
    from lxml import etree
    import time
    
    # 加入请求头,防止网站监测出来我们是爬虫,所以都必须要引入请求;对于有需要 登录 的页面需要加上cookices,那么直接在header字典中将 " 'Cookie': '你的cookie' "添加进去
    header={
       "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36"
    }
    
    # 遍历前10页的数据
    for a in range(10):
        # 此时的 url 根据range的区间不断变化的
        url = 'https://book.douban.com/top250?start={}'.format(a*25)
        # 1、获取网页的响应
        # url,请求头,请求延迟(时间):主要是在多批次访问的时候,有一个停顿时间,可以防止网站监测为爬虫,也就是伪造一个真实的人的请求
        response = requests.get(url, headers=header,timeout=10)
        # 2,当网页获取成功的之后,设置网页的编码格式,方式出现中文的乱码
        response.encoding='utf-8'
        
        # 3,从获取到的文本连接中获取对应的网页源代码字符串
        data = response.text
    
        # 4.对获取到的网页源代码字符串使用etree解析
        s=etree.HTML(data)
    
        # 5.遍历当前页中的所有table
        books=s.xpath("//*[@id='content']/div/div[1]/div/table")
        
        # 在执行到每一个url的时候,设置请求的延时时间,也就是说在请求一次之后隔多长时间再执行一次
        time.sleep(2)
        
        # 6.在table中指定相对路径,把书名、超链接、评分、描述依次获取出来,然后格式化打印输出
        for div in books:
            title = div.xpath("./tr/td[2]/div[1]/a/@title")[0]
            href =div.xpath("./tr/td[2]/div[1]/a/@href")
            score=div.xpath("./tr/td[2]/div[2]/span[2]/text()")[0]
            scrible=div.xpath("./tr/td[2]/p[2]/span/text()")
            # 由于在源代码中部分书籍的描述信息有的是空的,所以这里做了一个判断
            if len(scrible) > 0:
                print("{}: {},{},{}\n".format(title,score,href,scrible[0]))
            else:
                print("{}: {},{}\n".format(title,score,href))
    

    7.爬虫实战:爬取"笔趣阁小说网"中的一本小说

    '''
    第一个案例:爬取笔趣阁小说网中的一本小说
    '''
    
    import requests
    from bs4 import BeautifulSoup
    
    # 这个是爬虫请求时,设置的请求头文件,用将将爬虫伪装成模拟器就行请求网页,并不是所有的网页都需要headers,大部分get的网页都不需要
    headers = {
        "Host":"www.xbiquge.la",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36",
        "Cookie": "_abcde_qweasd=0; bdshare_firstime=1557364397358; Hm_lvt_169609146ffe5972484b0957bd1b46d6=1569634637; BAIDU_SSP_lcr=https://www.baidu.com/link?url=dyrbuFlzQnF2dvMKantPaFSxvBy7yw8kxfQKPGemmby&wd=&eqid=fbaeb37c0021021f000000025d8eb947; _abcde_qweasd=0; Hm_lpvt_169609146ffe5972484b0957bd1b46d6=1569637328"
    }
    
    # 定义一个变量,用来存放网址
    url = 'http://www.xbiquge.la/40/40520/'
    # 使用get请求去请求网页,这时候的返回值是一个代码(正确是200)
    res = requests.get(url)
    # 设置字符编码为utf-8,
    res.encoding ='utf-8'
    # 将res解析成text格式
    html = res.text
    
    # 使用BeautifulSoup将html解析成lxml格式,返回值类似于一个字符串,可以直接print,打印出来的东西看起来和html一样
    soup = BeautifulSoup(html,'lxml')
    # 查找网页中id为list的的div标签,这一步的作用是缩小查找的范围,方便我们查找我们想要的数据,返回值是一个类似是字符串吧,可以直接print
    div = soup.find('div',id='list')
    # 根据上边找到div标签,进一步查找我们需要的数据
    # 查找出div标签中所有的a标签,返回值是一个list
    list_a = div.find_all('a')
    
    # 创建或者读取一个文件,文件名为40520.txt,读写类型为覆盖(没有此文件的时候会自动创建,但是只能创建文件,不能创建目录),编码类型为utf-8
    fb = open("40520.txt",'w',encoding='utf-8')
    
    # 上边我们找到了所有的a标签,现在我们遍历list,挨个取出a标签
    # <a href="...">...</a>
    for a in list_a:
        # a标签中的href里有下一个页面的部分url,我们只需要将域名与href拼接起来就可以
        # 想要取出a标签的href直接a['href']即可
        href = "http://www.xbiquge.la"+a['href']
        print(href)
        # 类似于上边的res,同样还是请求网页
        response = requests.get(href,headers=headers)
        response.encoding='utf-8'
        html = response.text
        # print(response)
        soup = BeautifulSoup(html,'lxml')
        div = soup.find('div',id='content')
        # 如果我们想取出标签之间的文字,直接使用get_text()函数即可
        data = div.get_text()
    
        # 写入数据
        fb.write(a.get_text())
        fb.write('\n')
        fb.write(data)
        fb.write('\n')
    
    # 关闭文件
    fb.close()
    

    相关文章

      网友评论

          本文标题:数据采集-爬虫实战

          本文链接:https://www.haomeiwen.com/subject/ngpfkdtx.html