大数据采集与预处理之爬虫

期末内容:

第一章:爬虫是什么2

1爬虫的分类:通用爬虫和聚焦爬虫 

2区别和联系:

通用爬虫和聚焦爬虫在多个方面存在区别和联系。

  1. 定义:通用爬虫是搜索引擎使用的爬虫系统,旨在尽可能地抓取互联网上的所有网页,以便进行信息存储、分析和处理。而聚焦爬虫则是针对某一特定需求编写的爬虫程序,主要用于对特定网站的数据抓取和信息抽取。
  2. 使用场景:通用爬虫主要用于搜索引擎和web服务商,而聚焦爬虫则是针对特定需求进行设计和实现。
  3. 工作原理:通用爬虫的工作流程主要包括爬取网页、存储数据、内容处理和提供检索等步骤。在爬取网页时,通用爬虫遵循Robots协议,避免爬取无关或不合规的网页。而聚焦爬虫则是根据特定需求定制的程序,其工作原理与通用爬虫不同,需要根据具体需求进行设计和实现。
  4. 优缺点:通用爬虫的优点在于能够抓取大量网页,提供丰富的信息来源。但同时,通用爬虫也存在一些局限性,例如只能提供和文本相关的内容如html、pdf等,不能提供多媒体文件如音乐、图片、视频和二进制文件(脚本、程序)等。此外,通用爬虫的结果千篇一律,针对不同领域提供不同内容的能力有限。相比之下,聚焦爬虫的优点在于能够针对特定需求进行数据抓取和信息抽取,能够提供更加精准和深入的信息。但同时,聚焦爬虫也需要根据具体需求进行设计和实现,相对于通用爬虫来说开发难度更大。

综上所述,通用爬虫和聚焦爬虫在定义、使用场景、工作原理和优缺点等方面存在区别和联系。在实际应用中,应根据具体需求选择适合的爬虫类型,以达到最佳的信息获取效果。


第二章:爬虫的实现原理和技术4

1爬虫爬取网页的流程(DNS解析从对应IP地址将网页爬下来)

爬虫爬取网页的流程主要包括以下几个步骤:

  1. DNS解析:当爬虫程序需要访问某个网址时,首先需要通过DNS解析将网址转换为对应的IP地址。DNS解析是域名到IP地址的映射过程,通过DNS解析可以将网址转换为对应的IP地址,以便能够通过IP地址访问到相应的网页。
  2. 发起HTTP请求:一旦获得了IP地址,爬虫程序就会向目标服务器发起HTTP请求。HTTP请求是一种常见的网络请求方式,可以通过不同的HTTP方法(如GET、POST等)来获取或提交数据。
  3. 接收HTTP响应:当目标服务器接收到爬虫程序的HTTP请求后,会返回一个HTTP响应。HTTP响应包含了服务器对请求的处理结果,如网页的HTML内容、状态码、头部信息等。
  4. 解析网页内容:爬虫程序接收到HTTP响应后,需要解析响应内容以获取网页的数据。解析网页内容的方式有多种,如正则表达式、BeautifulSoup、lxml等。解析过程主要是提取网页中的所需信息,如标题、链接、图片等。
  5. 数据存储:解析得到的网页数据可以存储在本地文件、数据库或分布式存储系统中,以便后续处理和分析。
  6. 重复访问和更新:为了保持数据的实时性和完整性,爬虫程序需要定期或不定期地重复访问和更新目标网页,以便及时获取最新的数据。

需要注意的是,爬虫程序在爬取网页时需要遵循一定的规则和道德规范,如Robots协议、避免频繁访问导致目标服务器压力过大等。同时,对于一些特殊网站或敏感信息,还需要采取相应的措施来避免被封禁或引发法律问题。

2爬虫法律规范:robots君子协议,map文件

爬虫的法律规范主要包括以下几个方面:

  1. Robots协议:Robots协议是一种由互联网社区制定并遵循的君子协议,旨在规范爬虫程序的行为。Robots协议通常在网站的根目录下提供一个名为"robots.txt"的文件,其中列出了爬虫程序在爬取该网站时必须遵守的规则。这些规则包括禁止爬取的网页范围、抓取频率限制、跟随链接限制等。遵循Robots协议可以帮助爬虫程序遵守网站的访问权限限制,避免对网站服务器造成过大的压力。
  2. Map文件:Map文件是另一种常见的规范,用于指导爬虫程序如何正确地爬取网站。Map文件通常在网站的根目录下提供,其中列出了网站中每个网页的URL和对应的处理程序。通过遵循Map文件的指导,爬虫程序可以正确地抓取所需网页的内容和结构。

需要注意的是,尽管Robots协议和Map文件是一种自愿的君子协议,但违反这些协议可能会导致法律问题。在爬虫程序的开发和使用过程中,应当遵循相关法律法规和网站的规定,尊重网站的隐私和数据保护原则,避免对网站的正常运行造成干扰或损害。

3反爬方法(4种) 

反爬虫的方法主要包括以下几种:

  1. 限制访问频率:通过限制访问频率,可以防止爬虫程序对网站服务器造成过大的压力。常见的限制方式包括限制IP地址的访问频率、限制单个用户的访问频率、限制来自同一IP地址的并发请求数等。
  2. 检测并记录爬虫行为:通过检测和记录爬虫行为,可以及时发现并处理恶意爬虫程序。常见的检测方式包括检测访问日志、检测访问频率、检测访问路径等。
  3. 使用验证码:通过在登录、注册、重置密码等重要操作时加入验证码,可以防止恶意爬虫程序自动进行这些操作。验证码是一种用户验证方式,要求用户输入正确的字符或完成特定的任务才能继续操作。
  4. 加密敏感数据:通过加密敏感数据,可以防止爬虫程序获取到敏感信息,如用户密码、个人信息等。常见的加密方式包括对数据库中的敏感数据进行加密存储、对传输中的敏感数据进行加密传输等。

需要注意的是,反爬虫方法并不是绝对的,因为爬虫程序也可以采用相应的技术手段来绕过这些限制。因此,在使用反爬虫方法时,应当根据具体情况进行综合评估和选择,同时加强网站的安全防护措施,提高网站的安全性和稳定性。

4. 为什么选择Python作为爬虫的软件(3条及以上)

选择Python作为爬虫的软件的原因主要有以下几点:

  1. 语言简单易学:Python是一种解释型、高级编程语言,语法简洁明了,易于学习掌握。对于初学者来说,Python是一个很好的开始学习编程的选择,而且其强大的标准库和丰富的第三方库也使得开发更加方便。
  2. 丰富的第三方库:Python拥有丰富的第三方库,特别是Web开发、网络爬虫等领域。例如,Scrapy、BeautifulSoup、requests等库提供了强大的功能和易用的接口,可以方便地实现各种复杂的爬虫需求。
  3. 灵活的脚本功能:Python是一种脚本语言,具有很强的灵活性和可扩展性。使用Python编写爬虫程序可以更加灵活地处理数据和实现各种复杂的逻辑,而且Python也支持多种编程范式,可以更加高效地实现复杂的算法和数据结构。
  4. 社区支持:Python有一个活跃的开发者社区,可以为使用者提供丰富的资源和支持。在遇到问题时,可以方便地找到解决方案或者得到其他开发者的帮助。
  5. 与其他语言相比:与其他语言相比,Python在爬虫方面具有更高的性能和效率。例如,与Java相比,Python的执行速度更快,代码更加简洁;与JavaScript相比,Python在服务器端的应用更加广泛,而且Python的第三方库更加丰富和成熟。

综上所述,Python作为爬虫的软件具有语言简单易学、丰富的第三方库、灵活的脚本功能、社区支持和与其他语言相比的高性能和效率等优点。因此,Python成为了许多开发者和数据科学家在爬虫方面的首选语言。

第三章:网页请求原理2

浏览器浏览网页的过程:
浏览器通过DNS域名服务器查找对应的ip地址
向ip地址对应的web服务器发送请求
web服务器响应请求,发回html页面
浏览器解析html内容,并显示出来

浏览器显示完整网页的过程:
在浏览器地址栏中输入http://www.baidu.com,
浏览器会发送一个Request请求去获取http://www.baidu.com的HTML页面
服务器会把包含该页面的response对象返回给浏览器
浏览器分析页面中的内容发现其中引用了很多文件,包括image js文件等,所以浏览器会再次发送Request去获取这些图片 js文件。
当所有的文件下载完成,浏览器根据html的语法结构,将网页完整的显示出来

1.正常网站浏览网页

网页请求原理涉及到多个步骤和组件,当用户通过浏览器请求一个网页时,以下是一般的请求原理:

  1. DNS解析:用户在浏览器中输入网址(URL),浏览器首先需要通过DNS(域名系统)将网址解析为对应的IP地址。DNS服务器将域名映射到相应的IP地址,使浏览器能够找到存储网页内容的服务器。

  2. 建立TCP连接:浏览器通过解析得到的IP地址与Web服务器之间建立TCP(传输控制协议)连接。这个连接过程通常包括三次握手,以确保连接的成功建立。

  3. 发送HTTP请求:一旦TCP连接建立成功,浏览器会向Web服务器发送HTTP请求。HTTP请求包括请求行、请求头部和请求体。请求行指定了请求方法(如GET、POST等)、请求的资源路径和HTTP协议的版本。

  4. 服务器处理请求:Web服务器接收到HTTP请求后,会根据请求的资源路径找到相应的网页内容,并进行处理。服务器可能会执行一些后端逻辑,如数据库查询、用户认证等,以生成最终的网页内容。

  5. 发送HTTP响应:服务器处理完请求后,会构造一个HTTP响应并发送给浏览器。HTTP响应包括状态行、响应头部和响应体。状态行包含了响应的状态码,表示请求的处理结果(如200表示成功,404表示找不到资源)。

  6. 浏览器解析和渲染网页:浏览器接收到HTTP响应后,会解析响应中的HTML、CSS和JavaScript等内容,并根据浏览器的渲染引擎将其呈现给用户。浏览器会解析HTML标签,加载外部资源(如图片、字体等),并执行JavaScript代码,最终呈现出完整的网页界面。

以上是正常的网页请求原理。当用户通过浏览器访问一个网站时,浏览器会向服务器发送HTTP请求,服务器处理请求后返回相应的网页内容,浏览器再解析和渲染这些内容,最终展示给用户。爬虫程序模拟了这个过程,自动化地发送请求、接收响应,并提取所需的数据。然而,爬虫需要遵守网站的爬虫协议(如robots.txt)和法律法规,以确保合法、合规地获取数据。

2. URL与DNS系统

网页请求原理中,URL(统一资源定位符)与DNS(域名系统)系统起着关键的作用。

  1. URL:URL是用于标识互联网上资源的地址,它由协议类型、主机名和路径组成。当用户在浏览器中输入一个URL时,浏览器会根据这个URL向对应的服务器发起请求,以获取网页内容。
  2. DNS系统:DNS系统是一个分布式数据库系统,用于将域名转换为IP地址。当用户在浏览器中输入一个网址时,浏览器会通过DNS解析将网址转换为相应的IP地址,从而找到存储网页内容的服务器。DNS系统由多个DNS服务器组成,分布在全世界范围内,用于快速地完成域名到IP地址的转换。

在网页请求原理中,用户通过输入URL,浏览器会首先通过DNS系统进行域名解析,获取到对应的IP地址。然后,浏览器会使用这个IP地址与Web服务器建立TCP连接,并发送HTTP请求。服务器处理请求后,会返回相应的网页内容,浏览器再解析和渲染这些内容,最终展示给用户。

在这个过程中,URL起到了标识资源的作用,而DNS系统则负责将URL转换为相应的IP地址,以便浏览器能够找到存储网页内容的服务器。这两个组件是实现网页请求原理的关键部分。


第四章:数据爬取3

1.简单爬取

2.复杂爬取

3.响应状态码

在数据爬取过程中,响应状态码是一个重要的标识,用于表示请求是否成功以及服务器返回的结果状态。以下是一些常见的HTTP响应状态码及其含义:

  • 200 OK:请求成功,服务器已成功处理了请求。
  • 201 Created:请求成功,服务器已创建了新的资源。
  • 204 No Content:请求成功,但服务器没有返回任何内容。
  • 301 Moved Permanently:请求的资源已被永久移动到新位置。
  • 302 Found:请求的资源已被临时移动到新位置。
  • 304 Not Modified:客户端的缓存资源是最新的,服务器不需要返回任何内容。
  • 400 Bad Request:请求失败,请求中存在语法错误。
  • 401 Unauthorized:请求失败,需要进行身份验证。
  • 403 Forbidden:请求失败,服务器拒绝了请求。
  • 404 Not Found:请求失败,请求的资源不存在。
  • 500 Internal Server Error:服务器内部错误,无法完成请求。
  • 503 Service Unavailable:服务器暂时无法处理请求,可能是因为服务器过载或正在维护。

除了以上常见的状态码外,还有一些其他的状态码,用于表示不同的请求结果和服务器响应状态。在进行数据爬取时,需要注意根据响应状态码判断请求是否成功,并采取相应的处理措施。例如,如果遇到403 Forbidden状态码,可能表示爬虫被目标网站封禁或访问权限受限;如果遇到503 Service Unavailable状态码,可能表示服务器过载或维护中,需要等待一段时间再尝试爬取。


第五章:数据解析6

1.Xpath 

2. json path 

3. beautifulsoup

4.正则表达式

5 结构化数据与非结构化数据

数据解析是将数据从原始格式转化为结构化或可处理格式的过程。根据数据的不同形式,数据解析可以分为结构化数据解析和非结构化数据解析。

结构化数据是指具有固定格式或有限格式的数据,例如数据库中的表格、CSV文件等。这些数据通常以行列形式存储,每一行表示一个数据记录,每一列表示一个字段。结构化数据的解析相对简单,可以通过读取每一行和每一列的值来获取所需的数据。在Python中,可以使用pandas库来读取和解析结构化数据。

非结构化数据是指没有固定格式或有限格式的数据,例如文本、图像、音频和视频等。这些数据的形式多样,难以用统一的方式进行处理。非结构化数据的解析相对复杂,需要使用特定的方法和工具来提取所需的信息。例如,对于文本数据,可以使用自然语言处理(NLP)技术来提取关键词、情感分析等;对于图像数据,可以使用计算机视觉技术来识别物体、人脸等。

在数据解析中,还需要注意数据的清洗和去重等问题。数据清洗是指去除重复、缺失或不准确的数据,以确保数据的准确性和可靠性。数据去重是指在数据集中去除重复的记录或数据点,以避免对数据分析产生不必要的干扰或误差。在Python中,可以使用pandas库提供的drop_duplicates()函数来去除重复的记录。

6.路径(/  //  .  .. )

爬虫数据解析路径中的“/”、“//”、“.”和“..”分别表示不同的含义:

  1. “/”:表示根目录。在文件系统中,“/”表示整个文件系统的根目录,即所有文件和文件夹的起点。在URL中,“/”也常常被用作根目录的标识。
  2. “//”:表示绝对路径。在文件系统中,“//”用于表示绝对路径,即从根目录开始指定的完整路径。在URL中,“//”用于指定协议,例如“http://”或“https://”。
  3. “.”:表示当前目录。在文件系统中,“.”表示当前目录,即当前正在处理的目录。在URL中,“.”也用于表示当前目录或文件。
  4. “..”:表示上级目录。在文件系统中,“..”表示上级目录,即当前目录的上一级目录。在URL中,“..”也用于表示上级目录或上一级页面。

这些特殊字符在文件路径和URL中具有特定的意义,用于指示路径的相对位置或指向特定的资源。


第六章: scrapy框架3+2

Scrapy是一个用于Python的快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从中提取数据。Scrapy具有多用途和可定制的特点,它可以用于各种场景,包括数据挖掘、数据抽取、监控、分析、调查和开发API等。

以下是一些关于Scrapy框架的详细信息:

  1. 组件

    • 引擎 (Engine):控制数据流在所有组件之间的流动,并在相应动作发生时触发事件。
    • 调度器 (Scheduler):从URLs列表开始抓取,或接收由引擎派发的请求,并负责管理和分发请求。
    • 下载器 (Downloader):负责获取页面内容。一旦请求被调度,下载器负责获取请求的内容。
    • 爬虫 (Spiders):负责解析内容并提取数据。爬虫从下载器接收内容,然后解析并提取数据。
    • 项目管道 (Item Pipelines):处理爬虫提取的数据,例如将其存储到数据库中。
    • 下载器中间件 (Downloader Middlewares):提供了一种机制来拦截下载事件并在实际下载之前或之后进行处理。
    • 爬虫中间件 (Spider Middlewares):类似于下载器中间件,但是是在爬虫处理请求和响应时拦截。
  2. 功能

    • 快速抓取:Scrapy提供了快速和灵活的网络抓取能力。
    • 数据提取:Scrapy支持从HTML和XML内容中提取数据。
    • 可扩展性:可以使用第三方库或插件来扩展Scrapy的功能。
    • 错误处理:Scrapy具有内置的错误处理和异常捕获机制。
    • 持久性:可以存储请求和响应数据,以便在多个请求之间共享。
  3. 流程

    1. 引擎接收请求并将其发送给调度器。
    2. 调度器根据请求的优先级将其加入队列。
    3. 调度器将请求发送给下载器进行下载。
    4. 下载器下载页面内容并返回给爬虫。
    5. 爬虫解析页面内容并返回提取的数据(称为items)。
    6. 项目管道处理items,例如将其存储到数据库中。
  4. 指令:Scrapy使用命令行界面进行操作,以下是一些常用的指令:

    • scrapy startproject <projectname>:创建一个新的Scrapy项目。
    • scrapy genspider <spidername> <domain>:生成一个新的爬虫文件。
    • scrapy crawl <spidername>:运行一个爬虫并输出结果。
    • scrapy shell <url>:启动交互式Shell,用于测试解析函数等。
  5. 配置文件:Scrapy项目的配置文件是settings.py,其中包含了许多设置选项,例如代理设置、用户代理、跟踪重定向等。可以根据需要进行配置和修改。

编程题目


1、 请你利用所学知识完成任意网站的爬虫操作

import urllib.request

from urllib import request

url='https://tieba.baidu.com'

header={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.54'}

new_url=urllib.request.Request(url=url,headers=header)

response=urllib.request.urlopen(new_url)

html=response.read().decode()

print(html)

2、请你利用所学知识完成任意网站的爬虫操作,要求涉及用户输入及编码转换;
要求涉及User-agent头部信息的拼接,头部信息可用{User-agent:"mozilia"}代替

import urllib.parse

import urllib.request

url1='https://tieba.baidu.com/'

name=input("请输入要爬取的主题:")

url2=urllib.parse.quote(name)

url=url1+url2

header={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'}

new_url=urllib.request.Request(url=url,headers=header)

response=urllib.request.urlopen(new_url)

html=response.read().decode()

print(html)

3、请你利用xpath完成大案例的解析
要求:定义类及函数
首先完成当前页的爬取;
其次对当前页进行解析解析提取当前页的标题和标题对应的url地址
然后解析提取下一页的url地址 ,并对标题和标题对应的url地址进行保存操作
根据下一页的url地址继续爬取,继续进行以上步骤

from urllib import request,parse

from lxml import etree

class Tieba(object):

    def __init__(self,name):

        self.url = 'https://tieba.baidu.com/f?kw=%E7%94%B5%E5%BD%B1%E7%A5%A8%E6%88%BF'

        self.headers = {'user-agent': 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'}

    def get_data(self,url):

        req=request.Request(url=url,headers=self.headers)

        res=request.urlopen(req)

        response=res.read().decode()

        return response

    def parse_data(self,data):

        html=etree.HTML(data)

        el_list=html.xpath('//*[@id="thread_list"]/li/div/div[2]/div[1]/div[1]/a')

        print(len(el_list))

        data_list=[]

        for el in el_list:

            temp={}

            temp['title'] = el.xpath('./text()')[0]

            temp['link'] = 'https://tieba.baidu.com/' + el.xpath('./@href')[0]

            data_list.append(temp)

        try:

            next_url='https:'+html.xpath('//a[contains(thext(),"下一页“)]/@href')[0]

        except:

            next_url=None

            return  data_list,next_url

    def save_data(self,data_list):

        for data in data_list:

            print(data)

    def run(self):

        next_url=self.url

        while True:

            data =self.get_data(next_url)

            data_list,next_url=self.parse_data(data)

            data_list,next_url=self.parse_data(data)

            self.save_data(data_list)

            print(next_url)

            if next_url==None:

                break

if __name__=='__main__':

    tieba=Tieba('')

tieba.run()

4、利用jsonpath对任意网站内容解析,并提取内容

jsonpath

命令行 输入pip install jsonpath

5、利用正则表达式进行解析需利用re模块


6、利用beautifulsoup完成数据解析

import requests

from bs4 import BeautifulSoup

def get_text(url):

    try:

        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) '}  # 构建请求头

        res = requests.get(url, headers=headers)  # 发送请求

        res.encoding = res.apparent_encoding  # 设置编码格式

        res.raise_for_status()  # 是否成功访问

        return res.text  # 返回网页源代码

    except Exception as e:

        print(e)  # 抛出异常, 打印异常信息

def parse_province(text):  # 解析网页获取省份及其链接

    b_soup = BeautifulSoup(text, "html.parser")  # 构建BeautifulSoup对象

    ul_tag = b_soup.find(class_="txt3 center")  # 找到ul标签

    a_tags = ul_tag.select("li a")  # 找到所有a标签

    province_dict = {}  # 定义字典

    for item in a_tags:  # 循环遍历每一个超链接

        province_dict[item.string] = item["href"][2:]  # 以省份为键,链接为值构建字典

    province_dict.pop("海外")  # 删除不需要的记录

    return province_dict  # 返回结果

def get_schools_by_province(url):  # 获取某个省份的所有学校信息

    temp_content = get_text(url)  # 请求网页,得到网页源代码

    b_soup = BeautifulSoup(temp_content, "html.parser")  # 构建BeautifulSoup对象

    a_tags = b_soup.select("ul.l4 li a")  # 获取所有的学校超链接

    schools = []  # 定义列表,保存该省份所有的学校

    for item in a_tags:  # 循环遍历每一个标签

        schools.append(item.string)  # 获取标签内容即学校信息

    return schools  # 返回学校信息

if __name__ == '__main__':

    index_url = "https://daxue.911cha.com/"  # 起始页网址

    content = get_text(index_url)  # 请求网页获取源代码

    provinces = parse_province(content)  # 获取省份及其链接

    with open("schools.txt", mode="w", encoding="utf-8") as fp:  # 保存到文件

        for key, value in provinces.items():

            print("当前解析的省份为:", key, index_url + value)

            school_list = get_schools_by_province(index_url + value)  # 获取某个省份的院校列表

            for school in school_list:

                fp.write(",".join([school, key]) + "\n")  # 保存学校、省份信息,单独占一行

7、scrapy框架的理论知识三点

8、利用scrapy框架对任意网站实现爬取及解析操作

基础理论

爬虫概念:按照一定规则,自动请求万维网,并获取网页内容
爬虫法律规范:robots君子协议
爬虫限制:非法不允许(密码  明令禁止的)
服务器会做什么:反爬(检查你的信息(修改头部信息);
                           速度(降低速度);半永久封号(代理ip);验证码)
爬虫的分类:通用爬虫和聚焦爬虫
爬虫为什么选择python语言
爬虫的原理:模拟的正常网站的使用


200  ;404  403  500

浏览器浏览网页的过程:
浏览器通过DNS域名服务器查找对应的ip地址
向ip地址对应的web服务器发送请求
web服务器响应请求,发回html页面
浏览器解析html内容,并显示出来

统一资源定位符url:http://127.0.0.1:8080/subject/python/project.shtml
                               协议头 服务器地址和端口         文件路径
http和https的区别:SSL
http默认端口80 https默认端口443


ip地址(http://180.97.33.107)—为每一台计算机提供一个编号,非常不容易记忆和理解
所以发明了域名(http://www.baidu.com)代替ip地址

域名和ip地址之间的对应关系表—DNS服务器,完成ip地址和域名之间的映射

域名     ip地址

浏览器显示完整网页的过程:
在浏览器地址栏中输入http://www.baidu.com,
浏览器会发送一个Request请求去获取http://www.baidu.com的HTML页面
服务器会把包含该页面的response对象返回给浏览器
浏览器分析页面中的内容发现其中引用了很多文件,包括image js文件等,所以浏览器会再次发送Request去获取这些图片 js文件。
当所有的文件下载完成,浏览器根据html的语法结构,将网页完整的显示出来

楔子——抢票功能

通常涉及自动化地访问网页和提交表单的过程。使用Python编写爬虫可以实现这个功能。以下是一些步骤,以帮助你开始编写一个简单的抢票爬虫:

  1. 导入所需的库:你可能需要使用requests库实现网页的请求和响应,以及BeautifulSoup库来解析和提取网页内容。

  2. 发送请求:使用requests库发送HTTP请求,获取票务网站的页面内容。

  3. 解析页面:使用BeautifulSoup库解析网页的HTML内容,并通过标签、类名或其他属性来定位和提取所需的数据。

  4. 提交表单:如果需要登录或填写表单来购买票,你可以使用requests库发送POST请求,并提供所需的表单数据。

  5. 模拟操作:根据票务网站的操作流程和要求,模拟用户操作。这可能包括点击按钮、选择日期和座位等。

  6. 检查可用性:在提交表单之前,检查票的可用性。你可以根据返回的页面内容或其他标志来判断是否成功抢到票。

  7. 处理结果:根据抢票结果,发送通知或执行其他操作。例如,发送邮件或短信通知用户是否成功购买票。

需要注意的是,不同的票务网站可能有不同的反爬措施和限制,你可能需要了解和应对这些限制。此外,抢票属于自动化操作,务必遵守网站的使用规则和政策,以免触发反爬机制或违反法律法规。

1、爬取第一个网页


urlib库: python的内置库
urllib库包括3三大模块: urllib.request; urllib.error; urlib.parse
urlib.request:用于请求
uliberr: 处理异常
urllib.parse: 用于解析中文url编码转换,王%%% wd=济南职业学院https://www.baidu.com/s?
urlib.robotparser:专门解析robots协议


2、爬虫案例


导入库urlib 导入库中的模块request (两种导入方式)
调用库.模块中的具体函数urlopen- -该函数功能打开url地址用的
打开url地址返回response对象,利用.read)函数把对象中的内容读出来
读出来的对象内容为bytes数据类型,利用.decode("utf-8)转码方式把bytes数据类型转化为
国际化编码方式,从而保证原格式、中文能正常显示

import urllib.request
head={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0'}
url='https://www.baidu.com/'
new_url=urllib.request.Request(url=url,headers=head)
response=urllib.request.urlopen('new_url',timeout=10)
res=response.read().decode('utf-8')
print(res)

import urllib.parse
para1=urllib.parse.urlencode({'Use-Agent':'张三'})
para2=urllib.parse.urlencode('张三')
print(para1)
print(para2)


3、检查你的速度timesleep休眠时间 (后边讲)


服务器是否响应,多久响应,timeout超时, 超过此时间服务器不给响应的话,自己终止程序

4、三个小函数: geturl() getcode() info() urlopen


5、服务器响应:

1、正常响应; .
2、是爬虫报红;
3、是爬虫不报红; 4、 是爬虫一直等待区分好三个ruquest: Request请求; request模块, Request函数

为了更好的爬取页面内容,改头换面:更改urse-agent一- Request函数, 以下为更改步骤:
(1)首先正常访问页面,右击检查,查看网络中Request header信息中的User-Agent,
明确格式为字典值mozilla格式
(2)调用Ullib库中的request模块中的Request函数,实现重构头部信息操作
urlib.request.Request(url=url,headers=header)等号左边均为固定格式,等号右边均为单纯白
(3)重构好头部后,再用重构好头部的这个ur|地址进行发送请求和获取响应


6、urllib库中的parse模块

明确作用一般用于拼接url地址用:例如让用户输入,完成编码,完成
urlib.parse.urlencode(),此处urlencode函数要求,被编码的对象应为键值对的形式
urlib.parse.quote(),此处quote函数,不要求被编码对象为键值对形式

import urllib.parse
name=input('请你输入要爬取的主题:')
url2=urllib.parse.urlencode({'wd':name})
url1='https://www.baidu.com/s?'
url=url1+url2
print(url)

人生的第一个爬虫


#一、urllib库:python内置库
#pip install
#urllib库分为四个:urllib.request  urllib.parse  urllib.error  urllib.robots
#urllib.request:和请求相关
#urllib.parse:解析(中文)
#urllib.error:报错
#urllib.robots:第一步robots协议

#二
#1、导入库  导入模块  导入函数
import urllib.request
#from urllib import request
#2、学习函数 urlopen打开url地址用的
response=urllib.request.urlopen('https://www.baidu.com/')
#print(response)
#3、继续调用函数.read()读出来,对象中的内容
#res=response.read()
#print(res)
#bytes数据类型:格式不保留  中文没法显示
#用到函数.decode('utf-8')
#result=res.decode('utf-8')
#print(result)
#print(response.read().decode('utf-8'))#一步到位

#1正常响应 2爬虫报错 3爬虫不报错不给正确的 4爬虫一直等待
#timeout=

#http://httpbin.org/
#import urllib.request
#response=urllib.request.urlopen('http://httpbin.org/',timeout=0.28)
#print(response.read().decode('utf-8'))

#import urllib.request
#response=urllib.request.urlopen('http://httpbin.org/',timeout=0.28)
#print(response.read().decode('utf-8'))
#print(response.geturl())
#print(response.getcode())
#print(response.info())

# import urllib.request
# #1改头换面
# url="http://www.baidu.com/"
# header={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0'}
# url_total=urllib.request.Request(url=url,headers=header)
# response=urllib.request.urlopen(url_total)
# #2
# print(response.read().decode('utf-8'))

#import urllib.request
#url='http://www.baidu.com/'
#header={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0'}
#url_total=urllib.request.Request(url=url,headers=header)
#response=urllib.request.urlopen(url_total)
#print(response.read().decode('utf-8'))

import urllib.parse
#方便用户
name=input('请你的输入要爬取的百度页面内容关键字: ')#济南职业学院
urllib.parse.urlencode({'wd':name})#要求是键值对
# url2=urllib.parse.urlencode({'name':'张三'})
# print(url2)
# url2=urllib.parse.quote('山东商业职业技术学院')
# url1='https://www.baidu.com/s?wd='
# print(url1+url2)

#三、发送请求 获取响应

#(1)包装url地址(2)发送请求

header={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0'}
new_url=urllib.request.Request(url=url,header=header)
response=urllib.request.urlopen(new_url)
html=response.read().decode('utf-8')
print(html)
filename=name+'.html'
with open(filename,'w',encoding='utf-8')as f:
    f.write(html)

爬虫分为几步

拼接url地址

发送请求 获取响应

保存到本地

pn值:(页数-1)*50

class BaiduTiebaspide:
    def __init__(self):#初始化函数:放一些初始化的量
        #头部信息 url的结构
        pass
    def get_html(self):#发送请求 获取响应
        pass
    def parse_html(self):#解析
        pass
    def save_html(self):#保存
        pass
    def run(self):#控制函数的整体运行
        pass
class BaiduTiebaspide:...
if __name__=='__main__':
    spider=BaiduTiebaspide()
    spider.run()

import urllib.parse
import urllib.request
name=input('请你输入要爬取的主题:')
url2=urllib.parse.urlencode({'keyword':name})
url1='https://search.bilibili.com/all?'
url=url1+url2
print(url)
header={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'}
new_url=urllib.request.Request(url=url,headers=header)
# https://search.bilibili.com/all?keyword=%E6%97%A0%E5%8F%8C
response=urllib.request.urlopen(new_url)
html=response.read().decode('utf-8')
print(html)
filename=name+'.html'
with open(filename,'w',encoding='utf-8')as f:
    f.write(html)

import urllib.parse
import urllib.request

from pip._internal import req

print('')
class BaiduTiebaspider:
    def __init__(self):#初始化函数:放一些初始化的量
        #头部信息 url的结构
        self.header={'User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'}
        self.url='https://tieba.baidu.com/f?kw={}&pn={}'
    def get_html(self,url):#发送请求 获取响应
        urllib.request.Request(url=url,headers=self.header)
        res=urllib.request.urlopen(req)
        html=res.read().decode()
    def parse_html(self):#解析
        pass
    def save_html(self,filename,html):#保存
        with open(filename,'w',encoding='utf-8') as f:
            f.write(html)
    def run(self):#控制函数的整体运行
        name=input('请你输入要抓取的名称:')#李健
        params=urllib.parse.quote(name)#%%%%%%%
        start=int(input('请你输入起始页:'))#1
        end=int(input('请你输入终止页:'))#10
        for page in range(start,end+1):#page=1
            pn=(page-1)*50#pn=0
            url=self.url.format(params,pn)
            html=self.get_html(url)
            filename='{}_第{}页.html'.format(name,page)
            self.save_html(filename,html)
if __name__=='__main__':
    spider=BaiduTiebaspider()
    spider.run()

抛出异常与捕获异常

import urllib.request
try:
    response=urllib.request.urlopen('https://www.baidu.com/',timeout=0.01)
    print(response)
except Exception as error:
    print(error)
#异常的两种情况1
#URLERROR HTTPERROR
#http://sajndcuydsg.com
import urllib.request
import urllib.error
req=urllib.request.Request('http://sajndcuydsg.com')
try:
    urllib.request.urlopen(req)
except urllib.error.URLError as error:
    print(error)
# 异常的两种情况2
#URLERROR HTTPERROR
#http://www.itcast.cn/net
import urllib.request
import urllib.error
req=urllib.request.Request('http://www.itcast.cn/net')
try:
    urllib.request.urlopen(req)
except urllib.error.URLError as error:
    print(error)

正则

import re
title='你好,hello,世界'
pattern=re.compile(r"[\u4e00-\u9fa5]+")#查找中文
result=pattern.findall(title)
print(result)

10.8总结

#一、百度贴吧代码实现页面爬取

#二、学习两个小点
#学习抛出异常与捕获异常try except
#异常情况2种:urlerror   httperror

#三、数据解析技术
#要解析的内容分为两类:结构化的  非结构化的
#非结构化的:办公文档  文本  图像  部分html(先有数据 再有模型)
#结构化的:xml  json(先有模型 再有数据)

#根据网页类型不同,将数据解析技术分为以下几种:
#针对文本的解析:正则表达式
#针对HTML或者XML数据解析:xpath、beautifulsoup、正则
#针对json的解析:jsonpath

# import re
# title='你好,hello,世界'
# pattern=re.compile(r"[\u4e00-\u9fa5]+")#查找中文
# result=pattern.findall(title)
# print(result)

本节课已经掌握了爬虫的爬取和解析过程
下次课讲课本知识

10.13总结

0、介绍课本目录,了解前四周基础知识重要性
      明确熟练掌握的知识:爬虫  解析 框架
1、明确任务汇率
      安装flask框架   创建汇率文件   创建服务器网站
      回顾前4周爬虫知识   
      书写客户端爬虫代码

2、Get和Post方法
      Get 和Post方法在客户端程序写法的区别(重要)
      明确GET POST方法的区别:url地址的拼接,安全性;
      Get和Post方法在服务器端获取数据的方式完全一致;
      Get 和Post方法在路由选择中,默认选择的为get  指定post方式如何指定,两种均可如何指定;
      利用Get 和Post方法实现多个参数的设置利用&进行拼接。
      
3、正则表达式(课本p14页)

爬虫 解析 框架

安装flask框架 创建汇率文件 创建服务器网站 明确任务汇率

main.py

print("")
import urllib.request
response=urllib.request.urlopen('http://127.0.0.1:5000/')
print(response.read().decode())

rates.csv

print("")
import urllib.request
response=urllib.request.urlopen('')
print(response.read().decode())

sever.py

import flask
app=flask.Flask(__name__)
@app.route("/")
def index():
    f=open("rates.csv","r",encoding="utf-8")
    st="<table border='1'>"
    rows=f.readlines()
    for row in rows:
        s=row.split(",")
        if len(s)==6:
             st=st+"<tr>"
             for t in s:
                   st=st+"<td>"+t+"</td>"
             st=st+"</tr>"
    st=st+"</table>"
    f.close()
    return st
app.run()

import re
title='你好,hello,世界'
pattern=re.compile(r"[\u4300-\u9fa5]+")#查找中文
result=pattern.findall(title)
print(result)

1、数据解析


针对字符串——正则表达式
针对html xml ——xpath   beautifulsoup
针对json——jsonpath

2、正则表达式


import re
r引导“遵循语法”
\d  :    匹配数字0-9
b\d+: +多个(最少一次),b开头,匹配多个数字0-9
ab*  :*多个(最少0次)
ab?  :  ?重复?前边的字符(0次或者1次)
a.b  :字符a和字符b之间 可以放置任意的字符
ab|ba:满足ab字符可以,满足ba字符也可以
\n占据一个字符位置
空白符占据一个字符位置
\b表示匹配结尾空白位置
[0-9]表示0-9之间的字符任意一个均可
上尖括号出现在[]中的第一个位置,表示对整个[]中的内容取反(不取)
\s表示匹配空格(区别\b,可以表示非结尾 中间位置)
\w:大小写字母 数字均能匹配
上尖括号单独出现,不与[]联合出现,以上尖括号后边的字符作为开头
$表示以$前边的字符作为结尾

3、xpath
(1)xpath语法结构
/    //
.   选取当前节点
..  选取当前节点的父节点
@属性
[1]第一个
[last()]最后一个
last()-1倒数第二个
position()<3位置的前两个
/a[@lang="title"]
/a[@lang="title"]/b


(2)lxml解析库
目的:
response=urllib.request.urlopen(url)
res=response.read().decode()
print(type(res))
字符串——正则表达式
去字符串

牵涉到的三个类:
Element类——去节点字符串
ElementTree类——去字符串(网页树结构)
ElementPath类——树结构的寻址

(3)Element类——去节点字符串
lxml     etree
urllib   request
from lxml import etree
root=etree.Element('root')
print(root)

print(a.tag)#.tag表示获取节点的名称

添加属性1——创建节点 并为该节点添加属性
root=etree.Element('root',intersting='totally')
print(root)
print(type(etree.tostring(root)))

添加属性2——在原有节点基础之上 添加节点属性
root.set('age','30')
print(root)
print(etree.tostring(root))


(4)小函数-text()
root=etree.Element('root')
root.text='hello world'
print(root.text)
print(etree.tostring(root))

(5)
ElementTree类——去字符串(网页树结构)
三个函数:
fromstring()-从字符串中解析XML文档,返回根节点
XML()-从字符串中解析XML文档,返回根节点
HTML()-从字符串中解析HTML文档,返回根节点-自动加html body节点


(6)
ElementPath类——树结构的寻址
find()方法
root=etree.XML('<root><a x='123'>xtext</a></root>')
print(root.find('a').tag)
print(root.findall(".//a[@x]")[0].tag)

.urlopen()——response对象
.read()——读操作,bytes数据类型(节点)
.decode()——转码,格式保留  中文正常显示(字符串)

ElementTree类——去字符串(网页树结构)
ElementPath类——树结构的寻址

XPath

xml解析库

安装命令:python -m pip install lxml

import urllib.request
from lxml import etree
url='https://tieba.baidu.com/f?ie=utf-8&kw=%E6%B8%85%E5%8D%8E&fr=search'
header={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'}
new_url=urllib.request.Request(url=url,headers=header)
res=urllib.request.urlopen(new_url)
html=res.read().decode()
result=etree.HTML(html)
s=result.xpath('/html/body/div[3]/div/div[2]/div[2]/div[1]/div[3]/ul/li[2]/div[3]/a')
print(s)

from lxml import etree
root1=etree.XML("<root><a x='123'>xtest</a></root>")#把字符串转换为Xml
root2=etree.HTML("<root><a x='123'>xtest</a></root>")#把字符串转换为Html
root3=etree.fromstring("<root><a x='123'>xtext</a></root>")#把字符串转换为Xml
print(root1)
print(root2)
print(root3)
print(etree.tostring(root1))#完善结构
print(etree.tostring(root2))
print(etree.tostring(root3))
print(root3.find('a').tag)
print(root3.findall(".//a[@x]")[0].tag)

from lxml import etree

import first
import second

text = '''
<div>
    <ul>
        <li class="item-1">
            <a href="link1.html">first item</a>
        </li>
        <li class="item-1">
            <a href="link2.html">second item</a>
        </li>
        <li class="item-inactive">
            <a href="link3.html">third item</a>
        </li>
        <li class="item-1">
            <a href="link4.html">fourth item</a>
        </li>
        <li class="item-0">
            <a href="link5.html">fifth item</a>
    </ul>
</div> 
'''
result=etree.HTML(text)
a=result.xpath('//li[1]/a/text()')
b=result.xpath('//li[3]/a/@href')
print(a)
print(b)
import urllib.request
url='http://www.baidu.com'
res=urllib.request.urlopen(url)#response对象:封装
print(res)
req=res.read()#bytes数据类型
print(req)
result=req.decode()#字符串类型
print(type(result))
#爬虫:从左往右

百度贴吧

from urllib import request,parse
from lxml import etree

class Tieba(object):
    def __init__(self,name):
        self.url='https://tieba.baidu.com/f?kw=%E7%94%B5%E5%BD%B1%E7%A5%A8%E6%88%BF'
        self.headers = {'user-agent': 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'}
    def get_data(self,url):
        req=request.Request(url=url,headers=self.headers)
        res=request.urlopen(req)
        response=res.read().decode()
        return  response
    def parse_data(self,data):
        html=etree.HTML(data)
        el_list=html.xpath('//*[@id="thread_list"]/li/div/div[2]/div[1]/div[1]/a')
        print(len(el_list))
        data_list=[]
        for el in el_list:
            temp={}
            temp['title']=el.xpath('./text()')[0]
            temp['link'] ='https://tieba.baidu.com/'+el.xpath('./@href')[0]
            data_list.append(temp)
        try:
            next_url='https:'+html.xpath('//a[contains(text(),"下一页")]/@href')[0]
        except:
            next_url=None
        return data_list,next_url
    def save_data(self,data_list):
        for data in data_list:
            print(data)
    def run(self):
        next_url=self.url
        while True:
            data=self.get_data(next_url)
            self.parse_data(data)
            data_list,next_url=self.parse_data(data)
            self.save_data(data_list)
            print(next_url)
            if next_url==None:
                break
if __name__=='__main__':
        tieba=Tieba('')
        tieba.run()

beautifulsoup

#beautifulsoup和xpath很多一样,设计的目的解析xml  html
#字符串——正则    html xml——xpath beautifulsoup    json——jsopath
#直接拿过来就可以用

#一、完成buautifulsoup4安装
# 两种方法 安装buautifulsoup4:
# 命令方式  安装: pip3 install beautifulsoup4
# pycharm环境形式 安装:file  settings   project +   beautifulsoup4  安装  ok

#二、导入buautifulsoup类
# from bs4 import BeautifulSoup

#三、传入初始化参数
# soup=BeautifulSoup('html_doc','lxml')
# html_doc被解析的对象  lxml解析器进行解析

#xpath             lxml库  解析器
#beautifulsoup     lxml库  解析器;python标准库;html5lib解析器


#四、实例
# from bs4 import BeautifulSoup
# markup='<a href="http://example.com" rel="external nonfollow" rel="external nonfollow" rel="external nonfollow">l ike to <i>example.com</i></a>'
# soup=BeautifulSoup(markup,'lxml')
# # print(soup)
# # print(soup.prettify())
# print(soup.find_all('i'))
# print(soup.find_all('i','a'))
# print(soup.find_all(['i','a']))
# print(soup.find_all(rel="external nonfollow"))

 

pip3 install beautifulsoup4
import urllib.request
req=urllib.request.Request()
res=urllib.request.urlopen(req)
response=res.read().decode()

from bs4 import BeautifulSoup
soup=BeautifulSoup(,)
result=soup.find_all('')
print(soup.prettify())
print(result)
# import requests
# r=requests.get('https://python123.io/ws/demo.html')
# print(r.text)
# demo=r.text
# from bs4 import BeautifulSoup
# soup=BeautifulSoup(demo,'html.parser')
# print(soup.prettify())

import urllib.request
req=urllib.request.Request('https://www.icourse163.org/course/BIT-268001')
res=urllib.request.urlopen(req)
response=res.read().decode()
print(response)

from bs4 import BeautifulSoup
soup=BeautifulSoup(response,'lxml')
result=soup.find_all('div')
print(result)

json模块

# import requests
# import json
#
# url = "https://www.lagou.com/lbs/getAllCitySearchLabels.json"
# headers = {
#     'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36',
#     "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
#     "Accept-Encoding": "gzip, deflate, sdch",
#     "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4",
#     "Cache-Control": "max-age=0",
#     "Connection": "keep-alive"
# }
#
# response = requests.get(url, headers=headers)
# data = json.loads(response.text)
# cities = []
# for item in data:
#     cities.append(item["name"])
# print(cities)

import json
import jsonpath
import urllib.request
url='https://www.lagou.com/lbs/getAllCitySearchLabels.json'
header={'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
new_url=urllib.request.Request(url=url,headers=header)
res=urllib.request.urlopen(new_url)
response=res.read().decode()

response_json=json.loads(response)
print(jsonpath.jsonpath(response_json,"$..name"))

#json模块——键值对
#jsonpath寻址——多层嵌套字典 直接进行数据提取
# data={'key1':{'key2':{'key3':{'key4':{'key5':{'key6':'python'}}}}}}
# print(data['key1']['key2']['key3']['key4']['key5']['key6'])
#
# import jsonpath
# print(jsonpath.jsonpath(data,'$.key1.key2.key3.key4.key5.key6'))
# print(jsonpath.jsonpath(data,'$..key6'))

#jsonpath用于多层字典值嵌套进行寻址
import jsonpath
#输出python字符串
date={'key1':{'key2':{'key3':{'key4':{'key5':{'key6':'pytyhon'}}}}}}
print(date['key1']['key2']['key3']['key4']['key5']['key6'])
print(jsonpath.jsonpath(date,'$.key1.key2.key3.key4.key5.key6'))
print(jsonpath.jsonpath(date,'$..key6'))
import json
print(json)
#1、json模块——和字符串相关(加上字符串  去掉字符串)

去掉字符串——字符串带着(正则表达式)——json文档——jsonpath

加上字符串——保留最原本的样子(空格 缩进 全部保留)

去字符串 .loads()字符串    .load()文件(字符串)

加字符串.dumps()  .dump()

#json.loads()去掉字符串
import json
str_list='[1,2,3,4]'
str_dist='{"city":"济南","name":"小明"}'
print(type(str_list))
print(type(str_dist))
print(type(json.loads(str_list)))
print(type(json.loads(str_dist)))
#json.dump()加上字符串
import json
app_list=[
    {"name":"腾讯qq","link":"www.qq.com"},
    {"name":"新浪微博","link":"www.xinlang.com"},
    {"name":"王者","link":"www.****.com"}
]
with open('app.json','w',encoding='utf-8') as f:
    json.dump(app_list,f,ensure_ascii=False)

#json模块去字符串 加字符串
# import json
# json.dump()
# json.loads()
# 序列化:python转成字符串  (操作完 执行保存操作前 序列化)  json.dump()   json.dumps()
# 反序列化:把字符串转成python(寻址之前 对字符串 进行去字符串的操作) json.loads()   json.load()

#json.loads的用法
# import json
# str_list='[1,2,3,4]'
# str_dict='{"city":"北京","name":"小明"}'
# print(type(str_list))
# print(type(str_dict))
# print(type(json.loads(str_list)))
# print(type(json.loads(str_dict)))


#json.dump的用法
# import json
# app_list=[
#     {"name":"腾讯qq","link":"http://www.qq.com"},
#     {"name":"新浪微博","link":"http://www.xinlang.com"},
#     {"name":"吃鸡","link":"http://www.***.com"}
# ]
# with open('app.json','w',encoding='utf-8') as f:
#     json.dump(app_list,f,ensure_ascii=False)

json模块——字符串(加 减)

.load()     .load()     ——去字符串

.dump()  .dumps()  ——加字符串

json模块——键值对json数据(寻址用)

data="""{
    "store":{
        "book":[
            {"categore":"reference",
             "author":"Nigel Rees",
             "title":"saying of the Century",
             "price":8.95
            },
            {"categore":"fiction",
             "author":"J.R.R.Tolkien",
             "title":"The Lord of the Rings",
             "isbn":"0-395-19395-8",
             "price":22.99
            }
        ],
        "bicycle":{
            "color":"red",
            "price":19.95
        }
    }
}"""
import json
import jsonpath
data_json=json.loads(data)
jsonpath.jsonpath(data_json,"$..price")
jsonpath.jsonpath(data_json,"$..color")
# print(jsonpath.jsonpath(data_json,'$..color'))
# print(jsonpath.jsonpath(data_json,'$.''store.''book[0]'))
print(jsonpath.jsonpath(data_json,"$.'store'.'book'.*.'title'"))

框架——scrapy

运行

假如要处理一个网站,爬虫会告诉引擎,联络调度器进行排序入队,调度器执行完毕告诉引擎,引擎再告诉下载器(和互联网直连),下载器经过引擎将下载好的数据交给爬虫,爬虫经过引擎将数据交给管道保存。

scrapy框架工作流程代码实现

python -m pip install Scrapy 

python.exe -m pip install --upgrade pip

scrapy startproject Baidu

cd Baidu

scrapy genspider 爬虫名字 爬虫域(scrapy genspider baidu www.baidu.com)

scrapy crawl 爬虫名字——第六步

总结

爬虫

  1. 最简单的爬虫(60)

导入库urllib   导入模块request   函数urlopen()

url=“www.douban.com”

import urllib.request

response=Urllib.request.urlopen("www.douban.com") 

response.read().decode()

  1. 强化版爬虫(70)

导入库urllib   导入模块request   函数urlopen()

                               函数Request()

              导入模块parse    函数urlencode({kw:name})  kw=name

                               函数quote(name)  name 

‘www.douban.com/f?%%%%%%’

url=“www.douban.com”+%%%%%%

头部信息的拼接,user-agent

用户输入

import urllib.parse

import urllib.request

name=Input(“请你输入要爬取的关键字”)

kw=Urllib.parse.quote(name)

url=“www.douban.com/f?”+kw

header={user-agent:...}

new_url=Urllib.request.Request(url=url,headers=header)

response=Urllib.request.urlopen(new_url)

response.read().decode()

  1. 复杂版爬虫——(80)

#请你定义类tieba 定义方法 发送请求  解析 保存

Clsaa tieba:

 Def get_data(){

Pass}

Def parse_data(){

Pass}

Def save_data(){

Pass}

对爬虫爬取的内容进行解析

  1. 字符串(“yuahjkhdfsoiq”)——正则表达式  import re  看课本13-16
  2. Xml  html(“<html><a><b>”)——Xpath

   lxml   urllib

   Etree

Element:  .element()  .tostring()   .set()   .tag  .text()

Elementtree:   fromstring   XML   HTML

Elementpath:  .xpath(xpath语法规则 /  //  @)   xpathhelper

网页的解析

爬下来

解析1——当前页的标题和标题对应的url地址  .xpath(xpath语法结构)

                                           For循环 {} data_list=[]  [].append()

解析2——下一页的url地址  .xpath(xpath语法结构) //a[contains(text(),”下一页”)]/@href

  1. Beautifulsoup

安装pip3 install beautifulsoup4

导入类 from bs4 import Beautifulsoup

初始化Beautifulsoup(被解析,语法规则)

  1. Json

Json   .loads()   .dump()

Jsonpath  jsonpath(被寻址的内容,“$..”)

爬虫


最简单的爬虫(60)
导入库urllib   导入模块request   函数urlopen()
url=“www.douban.com”
Import  urllib.request
response=Urllib.request.urlopen("www.douban.com") 

response.read().decode()
强化版爬虫(70)
导入库urllib   导入模块request   函数urlopen()              函数Request()-重构头部信息              
导入模块parse    函数urlencode({kw:name})  kw=name                                 函数quote(name)  name  ‘www.douban.com/f?%%%%%%’
Url=“www.douban.com”+%%%%%%
头部信息的拼接,user-agent
用户输入
Import urllib.parse
Import urllib.request
Name=Input(“请你输入要爬取的关键字”)
kw=Urllib.parse.quote(name)
url=“www.douban.com/f?”+kw
Header={user-agent:...}
New_url=Urllib.request.Request(url=url,headers=header)
response=Urllib.request.urlopen(new_url)
response.read().decode()
复杂版爬虫——(80)
#请你定义类tieba 定义方法 发送(请求)  解析 保存
Class tieba: 
Def get_data(){
              Pass}
Def parse_data(){
             Pass}
Def save_data(){
             Pass}
对爬虫爬取的内容进行解析
1  字符串(“yuahjkhdfsoiq”)——正则表达式  import re  看课本13-16
2  Xml  html(“<html><a><b>”)——Xpath   lxml   urllib   Etree
Element:  .element()  .tostring()   .set()   .tag  .text()
Elementtree:   fromstring   XML   HTML
Elementpath:  .xpath(xpath语法规则 /  //  @)   xpathhelper

网页的解析

爬下来
解析

1——当前页的标题和标题对应的url地址  .xpath(xpath语法结构)                                            For循环 {} data_list=[]  [].append()
解析2——下一页的url地址  .xpath(xpath语法结构) //a[contains(text(),”下一页”)]/@href
3  Beautifulsoup
安装pip3 install beautifulsoup4
导入类 from bs4 import Beautifulsoup
初始化Beautifulsoup(被解析,语法规则)
4  Json
Json   .loads()   .dump()
Jsonpath  jsonpath(被寻址的内容,“$..”)

### 数据采集预处理期末实验报告:基于Scrapy框架的爬虫项目 #### 一、概述 本实验旨在通过构建一个简单的Web爬虫来理解数据采集的过程及其关键技术。此过程不仅涉及到如何高效地抓取网页内容,还包括了解并应用Python网络编程、异步编程以及应对各种反爬策略的方法[^1]。 #### 二、环境搭建 为了顺利完成本次实验,在开始之前需安装好必要的开发工具和库文件,主要包括但不限于: - Python解释器版本3.x以上; - 安装`scrapy`包以及其他辅助依赖项; #### 三、核心模块设计 ##### (一)定义Spider类 创建一个新的spider子类继承自`scrapy.Spider`,设置name属性用于唯一标识该蜘蛛实例,并指定start_urls列表作为初始请求地址集合。 ```python import scrapy class ExampleSpider(scrapy.Spider): name = 'example' start_urls = ['http://quotes.toscrape.com/page/1/', ] def parse(self, response): pass ``` ##### (二)编写解析函数 针对每一页返回的内容制定相应的提取逻辑,通常会利用XPath表达式或者CSS选择器获取所需字段的信息片段。 ```python def parse(self, response): for quote in response.css('div.quote'): yield { 'text': quote.css('span.text::text').get(), 'author': quote.css('small.author::text').get(), 'tags': quote.css('a.tag::text').getall() } next_page = response.css('li.next a::attr(href)').get() if next_page is not None: yield response.follow(next_page, self.parse) ``` ##### (三)配置Item Pipeline 当item对象被传递给pipeline之后,则可以对其进行清洗、验证甚至持久化存储操作。 ```python from itemadapter import ItemAdapter class SaveToFilePipeline(object): def open_spider(self, spider): self.file = open(spider.name+'.jsonl', mode='w') def close_spider(self, spider): self.file.close() def process_item(self, item, spider): line = json.dumps(ItemAdapter(item).asdict()) + "\n" self.file.write(line) return item ``` #### 四、运行测试 完成上述编码工作后即可执行命令启动爬虫任务,观察控制台输出日志确认整个流程是否正常运作。 ```bash scrapy crawl example ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值