【文本网站的分析】

文本反爬网站的分析和爬取

一、实验目的

熟悉使用Selenium、Pyppeteer等工具爬取网站基本内容,通过分析具有文本反爬技术网站,设计爬取策略来获取文本正确的内容。

二、实验预习提示

1、安装Python环境 (Python 3.x):Pychram社区版+Anaconda

2、为Python安装Selenium、PyQuery库(打开pycharm新建项目,选择Anaconda创建的Python环境,在下面对应Console窗口执行):

pip install selenium
pip install pyquery

3、安装Chrome和对应ChromeDriver:
下载安装完后查看Chrome版本:点击 Chrome 的菜单,帮助 -> 关于 Chrome,即可查看 Chrome 的版本号105.0.5195.127,如图所示:
在这里插入图片描述

在ChromeDriver 官方网站https://sites.google.com/chromium.org/driver/downloads下载Chrome版本对应的驱动(105.0.5195.x, 看主版本号105都行),点击下划线的链接,根据系统型号下载。windows下chromedriver_win32.zip,其他系统找到对应版本下载::
在这里插入图片描述在这里插入图片描述

运行代码前配置系统环境变量Path前指定chrome driver位置:
Path=替换为chrome driver解压后的位置
或者在Pycharm运行配置指定:
在这里插入图片描述

三、实验内容

爬取网站:https://antispider3.scrape.center/

在这里插入图片描述

使用浏览器开发者工具(F12),分析网站结构和其中文本反爬机制,编码实现获取该网站每本书的封面图片URL、书名和作者信息。实验基框架代码见文档末资料。

四、实验要求

基本要求(60分): 将网站一页每本书的信息保存在一个josn文件中,每个json文件命名为:书名.json,其内容为保存书籍相应的信息:

{
  "title": "Wonder",
  "cover_url":"https://img1.doubanio.com/view/subject/l/public/s27252687.jpg",
  "authors":"R. J. Palacio"
}

实现方法不一定要用Selenium、Pyppeteer,但是必须是Python编写的,并以完成实验要求为准,并附上代码运行结果。

改进要求A(80分,选做): 在完成基本要求的基础上,选项一:实现可以遍历网站的每一页来爬取书籍信息。或指定爬取条目数量,当爬取总条目满足数量后停止爬取。选项二:或者举例至少三个其他网站的文本爬虫技术,分析并给出解决方案,不需要实现。

改进要求B(100分,选做): 在完成改进要求A的选项一的基础上,可以爬取书籍的额外信息,如评分,出版时间,出版社,ISBM, 价格等。
在这里插入图片描述

五、实验过程

1.基本要求: 将网站一页每本书的信息保存在一个josn文件中,每个json文件命名为:书名.json,其内容为保存书籍相应的信息。

1)导入相关包

import json
import warnings
from selenium import webdriver
from pyquery import PyQuery as pq
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from bs4 import BeautifulSoup

2)通过selenium获取网页数据,初始化浏览器对象,访问网页源码,设置等待时间,以字符串形式初始化html。

def get_data(url):
    data =url
    #反爬
    warnings.filterwarnings('ignore')
    browser = webdriver.Chrome()
    browser.get(data)
    WebDriverWait(browser, 10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.item')))
    html = browser.page_source
    doc = pq(html)

3)使用BeautifulSoup解析网页

 # 使用BeautifulSoup进行解析网页
    object= BeautifulSoup(doc.html(), "html.parser")
    browser.close()
    # 书籍标签
    tags = object.select("h3.name")
    # 书籍名称
    names = []
    # 书籍作者
    authors = []
    # 书籍图片
    pics = []

4)根据标签分析处理数据,获取书籍名称、书籍作者、书籍图片。获取书籍名称中,由于书籍名称的不同存储位置,需要分别获取书籍名称。通过lambda表达式控制文本,改变文本顺序。

 # 获取书籍名称
    for tag in tags:
        #h3标签
        if "whole" in tag.attrs['class']:
            names.append(tag.text)
        else:
            #多个span元素
            chars = tag.select("span.char")
            chars = sorted(chars, key=lambda a: eval(a.attrs['style'][6:-3]))
            name = ""
            for char in chars:
                name += char.text.strip()
            names.append(name)

    # 获取书籍作者
    for tag in object.select("p.authors"):
        authors.append(tag.text.strip().replace(" ", "").replace("\n", ""))
        print()

    # 获取书籍图片
    for tag in object.select("img.cover"):
        authors.append(tag.text.strip().replace(" ", "").replace("\n", ""))
        pics.append(tag.attrs['src'])

5)运用json文件保存数据,每个json文件命名为:书名.json,json文件内容为书籍名称、书籍封面、书籍作者。

  for i in range(len(names)):
            #json
            book = {"title": names[i],
                    "cover_url": pics[i],
                    "authors": authors[i],
                    
                    }
            data_path = f'{book["title"]}.json'
            json.dump(book, open(data_path, 'w', encoding='utf-8'), ensure_ascii=False, indent=2)

6)爬取过程及结果:

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

Wonder.json:

在这里插入图片描述

人间失格.json:

在这里插入图片描述

2.改进要求A: 在完成基本要求的基础上,实现可以遍历网站的每一页来爬取书籍信息。

1)加入页面链接列表:

Links = [ ]

2)查找页面标签,获取链接内容,遍历页面链接。

# 获取书籍链接
    tags = object.find_all('div', class_='el-col el-col-24')
    print(len(tags))

    for tag in [tags[i] for i in range(len(tags))]:
        link = tag.find('a')
        link = link.get('href')
        links.append('https://antispider3.scrape.center' + link)
    print(links)
    return names, authors, pics, links

3)加入json文件,保存书籍数据,实现遍历网页爬取数据。

 for i in range(len(names)):
            #json
            book = {"title": names[i],
                    "cover_url": pics[i],
                    "authors": authors[i],
                    "link": links[i],
                    
                    }
            data_path = f'{book["title"]}.json'
            json.dump(book, open(data_path, 'w', encoding='utf-8'), ensure_ascii=False, indent=2)

4)网页前两页书籍爬取结果:

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

查理九世10·最后的古寺神佛.json:

在这里插入图片描述

设计诗.json:

在这里插入图片描述

3.改进要求B: 在完成改进要求A选项一的基础上,爬取书籍的额外信息,评分,价格出版社,出版时间,页数,ISBM。

1)通过BeautifulSoup解析文件,依次对每个标签进行查找处理,获取相应的书籍信息。其中需要注意书籍中没有出版社或者书籍页面的情况,需要做出更改。

def deal_data(url):
    data= url
    warnings.filterwarnings('ignore')
    browser = webdriver.Chrome()
    browser.get(data)
    WebDriverWait(browser, 30).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.item')))
    html = browser.page_source
    doc = pq(html)

    # 使用BeautifulSoup解析网页
    object = BeautifulSoup(doc.html(), "html.parser")
    #score
    score = object.find('span', class_='score m-r m-b-sm')
    if (score != None):
        score = score.text
    else:
        score = ' '
    #price
    price =object.find('p', class_='price')
    if (price != None):
        price = price.text
    else:
        price = ' '
    #publisher
    publisher = object.find('p', class_='publisher')
    if (publisher != None):
        publisher = publisher.text
        publisher = str(publisher).replace(' ', '').replace('\t', '').replace('\n', '').split(':')[1]
    else:
        publisher = ' '
    #publishtime
    publishtime = object.find('p', class_='published-at')
    if (publishtime != None):
        publishtime = publishtime.text
        publishtime = str(publishtime).replace(' ', '').replace('\t', '').replace('\n', '').split(':')[1]
    else:
        publishtime = ' '
    # pages
    page = object.find('p', class_='page-number')
    if (page != None):
        page = page.text
        page = str(page).replace(' ', '').replace('\t', '').replace('\n', '').split(':')[1]
    else:
        page = ' '
    #isbn
    isbn = object.find('p', class_='isbn')
    if (isbn != None):
        isbn = isbn.text
    else:
        isbn = ' '

    score = str(score).replace(' ', '').replace('\t', '').replace('\n', '')
    price = str(price).replace(' ', '').replace('\t', '').replace('\n', '').split(':')[1]

    isbn = str(isbn).replace(' ', '').replace('\t', '').replace('\n', '').split(':')[1]
    print(score)
    print(price)
    print(publisher)
    print(publishtime)
    print(page)
    print(isbn)
    browser.close()
    return score, price,publisher, publishtime, page,isbn

2)调用函数,遍历数据。

if __name__ == '__main__':
    #url地址
    url = "https://antispider3.scrape.center/page/"
    for i in [i for i in range(1, 3)]:
        names, pics, authors, links = get_data(url+ str(i))
        scores, prices, publishers, publishtimes, pages,isbns = [], [], [], [], [], []
        for link in links:
            print(link)
            score, price, publisher,publishtime, page, isbn = deal_data(link)
            scores.append(score)
            prices.append(price)
            publishers.append(publisher)
            publishtimes.append(publishtime)
            pages.append(page)
            isbns.append(isbn)

3)将书籍的评分、价格、出版社、出版时间、页面数、ISBM加入json文件,保存书籍信息。

        for i in range(len(names)):
            #json
            book = {"title": names[i],
                    "cover_url": pics[i],
                    "authors": authors[i],
                    "link": links[i],
                    "score": scores[i],
                    "price": prices[i],
                    "scpublisherores": publishers[i],
                    "publishtime": publishtimes[i],
                    "page": pages[i],
                    "isbn": isbns[i],
                    }
            data_path = f'{book["title"]}.json'
            json.dump(book, open(data_path, 'w', encoding='utf-8'), ensure_ascii=False, indent=2)

4)爬取结果:

人间失格.json:

在这里插入图片描述

最美遇见你.json:

在这里插入图片描述

总结: 运用selenium、pyquery、beautifulsoup方法,成功实现遍历爬取网站中书籍的各类信息,并json文件保存书籍信息。

六、资料

1.实验框架代码:

from selenium import webdriver
from pyquery import PyQuery as pq
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
browser = webdriver.Chrome()
browser.get('https://antispider3.scrape.center/')
WebDriverWait(browser, 10) \
    .until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.item')))
html = browser.page_source
doc = pq(html)
names = doc('.item .name')
for name in names.items():
print(name.text())

2.OpenSSL:Win32/Win64 OpenSSL Installer for Windows - Shining Light Productions (slproweb.com)

3.Josn存储,先安装json包:

import json
book = {"title": "Wonder",
    "cover_url":"https://img1.doubanio.com/view/subject/l/public/s27252687.jpg",
    "authors":"R. J. Palacio"
    }
data_path = f'{book["title"]}.json'
json.dump(book, open(data_path, 'w', encoding='utf-8'), ensure_ascii=False, indent=2)

4.实验小提示

可以根据HTML结构发现每个书籍信息都保存在。有的书名放在class="name whole"的H3元素,有书名由多个class="char"的SPAN元素组成。对于放在H3元素的书名,直接取出其元素内容即可,而对于放在多个SPAN元素中的书名,这里用到了文本反爬机制,利用CSS控制文本偏移来实现文本顺序改变。但不难发现其文本偏移由left属性决定原文正确顺序,因此需要按偏移left属性值大小升序排序获取正确的文本顺序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值