python爬虫学习--基础

爬虫学习:☠️

一.爬虫基础知识

1.1爬虫开发使用的开发环境

"""
Python3.7
系统环境:Mac(windows、linux都行)
编辑器:Pycharm
网页下载:requests
网页解析:BeautifulSoup/bs4
网页分析:chrome浏览器(用到了EditThisCookie插件)
"""

1.2 cmd安装对应的第三方包

 "requests"
C:\Users\xxq\AppData\Local\Programs\Python\Python37\python.exe -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests

 "BeautifulSoup4"
C:\Users\xxq\AppData\Local\Programs\Python\Python37\python.exe -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple BeautifulSoup4
      
 "selenium"
C:\Users\xxq\AppData\Local\Programs\Python\Python37\python.exe -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple selenium
        
import requests
from bs4 import BeautifulSoup
import  selenium
print("ok")
#脚本输出无报错.说明三个包安装完毕

1.3 爬虫架构(三大模块)

1.URL管理器:通过set存储已爬取网页的url,防止陷入死循环
2.网页下载器:通过网页下载器获取url对应的内容,已经根据不同的前端页面例如反爬、java动态验证等页面,爬取后生成html
3.网页解析器:网页下载器将url中的内容爬取完成后生成对应的html,通过解析html获取有用内容或新的url传入url管理器,爬取新的数据
#核心模块为以上三个模块,只要url管理器有新的url生成爬虫程序就不会死掉
4.爬虫调度端:针对爬虫程序进行管理,生命周期由它进行拓展和维护!
5.价值数据:将网页解析器获取到的数据,写入到mysql或redis等数据库中进行存储!

python爬虫学习--基础_第1张图片

二.爬虫的重要组件

2.1 request网页下载库

1.python程序如何通过request到达网页服务器?
#request会发送一个request请求到目标网页服务器中,并在请求体中添加header和请求内容info
#服务器拿到请求后会进行解析,并将请求的内容response(响应)返回headers、cookies等服务器返回的内容

2.2 发送request请求

发送request请求
#requests.get/post(url,params,data,headers,timeout,verify,allow_redirects,cookies)
#url:要下载的目标网页的URL
#params:字典形式,设置URL后面的参数,比如?id=123&name=xiaoming
#data:字典或者字符串,一般用于POST方法时提交数据
#headers:设置user-agent、refer等请求头
#timeout:超时时间,单位是秒
#verify:True/False,是否进行HTTPS证书验证,默认是,需要自己设置证书地址
#allow_redirects:True/False是否让requests做重定向处理,默认是
#cookies:附带本地的cookies数据              --cookies保持登陆状态.(账号、密码)

2.3 接收response响应

接收response响应
#r = requests.get/post(url)

// 查看状态码,如果等于200代表请求成功
#r.status_code
// 可以查看当前编码,以及变更编码
// (重要!requests会根据Headers推测编码,推测不到则设置为ISO-8859-1可能导致乱码)
#r.encoding
// 查看返回的网页内容
#r.text
// 查看返回的HTTP的headers
#r.headers
// 查看实际访问的URL
#r.url 
// 以字节的方式返回内容,比如用于下载图片
#r.content
// 服务端要写入本地的cookies数据
#r.cookies

2.4 爬取简单网站

import requests
url = "http://www.crazyant.net"
#定义要爬取的url
r = requests.get(url)
#定义要发送的http请求方式
print(r.status_code)
#打印状态码.此时r为response(响应)
print(r.headers)
#打印请求体返回的请求头,即是否是长连接、压缩传输、格式、字符集、前端服务器等
print(r.text)
#展示网页内容用text
print(r.encoding)
#打印网页字符集
print(r.cookies)
#打印cookies

##httpcn.com爬取
import requests
url = "http://www.httpcn.com"
r = requests.get(url)
print(r.status_code)
print(r.headers)
#观察headers无chart标识
#可以通过text中的media查看字符集或者网站源码
r.encoding="utf-8"
#指定解析的字符集格式
print(r.text)
#再次打印爬取内容为中文

2.5 URL管理器

1.对爬取URL进行管理,防止重复和循环爬取,支持新增URL和取出URL
#解释说明
#要实现对url的管理,防止重复和循环爬取,而且要新增url和取出url
1.需要对外提供俩个api接口
#取出一个带爬取的url以及新增一个待爬取的url
2.中层实现逻辑
#取出一个待爬取的url,url状态变为爬取中
#新增一个待爬取的url,通过已存在list或set进行判断是否以及存在
#通过中层实现防止重复和循环爬取
3.数据存储
分为三种方式:
01:python内存方式--待爬取的url为set集合:防止重复、已爬取的url也为set集合:一致性
    #python内存方式运行会导致程序停止后,二次运行数据丢失.一般采用redis方式运行
02:redis:缓存数据库中进行存储
#此方式最为首选.
03:mysql中利用关系型数据库进行存储url的状态
#新增俩个字段,一个url一个状态

python爬虫学习--基础_第2张图片

2.6 url管理器py

1.新增python软件包(因为url管理器,比较常用所以写完python软件包.方便调用)
##Dictionary

Dictionary
#在pycharm中就是一个文件夹,放置资源文件,对应于在进行JavaWeb开发时用于放置css/js文件的目录,或者说在进行物体识别时,用来存储背景图像的文件夹。该文件夹其中并不包含_ _ init.py_ _文件
Python package
#对于Python package 文件夹而言,与Dictionary不同之处在于其会自动创建_ _ init__.py文件。 简单的说,python package就是一个目录,其中包括一组模块和一个_ _ init__.py文件。
##例如:import utilfs.url_manager         #utilfs为自创的包名,url_manager为通用py文件
2.因为url管理器比较典型,其中包含了数据和不同状态的url集合,以及对外暴漏接口.所以要封装为class

class UrlManager():
    """
    url管理器
    """

    def __init__(self):
        self.new_urls = set()  #放待爬取的url
        self.old_urls = set()  #放已爬取的url
    #初始化构造函数
    #用俩个python_set.定义待爬取的url和已爬取的url
    def add_new_url(self,url):
        if url is None or len(url) == 0:
            return
        #如果传入的url为空或无内容,直接返回return则无法添加至set集合中
        if url in  self.new_urls or url in self.old_urls:
            return
        #判断传入的url如果在待爬取的url或已爬取的urlset中,那么则无法爬取
        else:
            self.new_urls.add(url)
            #如果不存在于上方俩个集合中,那么则为没有爬取过的url.新增到待爬取的urlset中

    def add_new_urls(self,urls):
        if urls is None or len(urls) == 0:
            return
        # 如果传入的url为空或无内容,直接返回return则无法添加至set集合中
        for url in urls:
            self.add_new_url(url)
            #如果存在多个url.通过for循环方式.写入到待爬取的列表中
            #每个方法都是独立的个体,都最后落入初始化中的俩个url集合中
    def get_url(self):
        if self.has_new_url():
            #如果待爬取的set中有内容
            url = self.new_urls.pop()
            #那么就取出set中的一个url并返回复制给定义的url
            self.old_urls.add(url)
            #然后在爬取完毕的url中追加一个pop出来的url
            return url
        #返回pop爬取的url
        else:
            return None
    def has_new_url(self):
        return len(self.new_urls) > 0
    #如果待爬取的url中有内容则返回个数
if __name__ == "__main__":
    """
    简单来说,该语句用来当文件当作脚本运行时候,就执行代码;但是当文件被当做Module被import的时候,就不执行相关代码。
    最顶层的__name__,将会被设置成了__main__,导入的模块中的__name__就被设置成了模块的名称
    因此也可以用if __name__ == “__main__”来判断你的模块代码是不是被当作最顶层模块在使用。
    
    --单独执行此脚本,可以用上方的写法.会执行下放的内容,如果是引入的方式则不会执行下发的内容,会返回false
    """
    url_manger = UrlManager()
    #定义对象来引用class
    url_manger.add_new_url("url1")
    #调用class中的add方法,未初始化中的set赋值
    url_manger.add_new_urls(['url1','url2','url3'])
    #因为有可能是获取到多个url,所以写多个url进行赋值,并测试去重复功能
    print(url_manger.new_urls,url_manger.old_urls)
    #打印出待爬取的集合url和已爬取的url

    print("#" * 30)
    new_url = url_manger.get_url()
    print(url_manger.new_urls,url_manger.old_urls)

    print("#" * 30)
    new_url = url_manger.get_url()
    print(url_manger.new_urls, url_manger.old_urls)

    print("#" * 30)
    new_url = url_manger.get_url()
    print(url_manger.new_urls, url_manger.old_urls)

    print("#" * 30)
    print(url_manger.has_new_url())
    #查看待爬取的列表是否为空

你可能感兴趣的:(#,python基础,python,爬虫,学习)