• Python爬虫入门


    什么是爬虫

    爬虫就是程序,一个能获取互联网上的资源(文字、图片、音视频)数据的程序。
    不用爬⾍, 打开浏览器, 输⼊百度的⽹址,就能在浏览器上看到百度的内容了。那换成爬⾍呢? 道理是⼀样的。只不过,是⽤代码来模拟⼀个浏览器, 然后同样的输⼊百度的⽹址。那么程序也能拿到百度的内容

    爬虫合法吗

    爬虫在法律上暂时是不被禁止的。但服务器上的数据有产权归属,如果网络爬虫获取数据后牟利将带来法律风险。小规模,数据量小,频率不高, 不窃取用户隐私的爬取是可以的,合法的

    反爬与反反爬

    反爬机制:网站可以通过制定相应的策略或者技术手段,防止爬虫程序进行网站数据的爬取
    反反爬策略:爬虫程序可以通过制定相关的策略或者技术手段,破解网站中具备的反爬机制,从而可以获取网站中相关的数据。
    robots.txt协议:君子协议。规定了网站中哪些数据可以被爬虫爬取哪些数据不可以被爬取

    requests请求库

    • 安装
    pip install requests
    
    • 1
    • 请求百度首页源代码
    import requests
    
    # 这样运行的话就把百度首页的html提取出来了
    url = "https://www.baidu.com/"
    response = requests.get(url)
    response.encoding = "utf-8"
    print(response.text)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    XPath解析库

    • ⼤多数情况下, 我们并不需要整个⽹⻚的内容, 只是需要那么⼀⼩部分。所以我们要做数据解析和提取。常见的有:xpath解析、BeautifulSoup解析、正则表达式re解析
    • XPath是⼀⻔在 XML ⽂档中查找信息的语⾔, XPath可⽤来在 XML⽂档中对元素和属性进⾏遍历,⽽我们熟知的HTML恰巧属于XML的⼀个⼦集,所以完全可以⽤xpath去查找html中的内容
    • 在python中想要使⽤xpath,需要安装lxml模块:pip install lxml
    • 基础用法:①将要解析的html内容构造出etree对象②使⽤etree对象的xpath()⽅法配合xpath表达式来完成对数据的提取
    html = """
    
    
        
            
            Title
        
        
            
            
    1. ⻜机
    2. ⼤炮
    3. ⽕⻋
    李嘉诚
    胡辣汤
    """
    from lxml import etree tree = etree.XML(html) result = tree.xpath("/html/body/ul/li/a/@href") print(result) result = tree.xpath("/html/body/ul/li") for li in result: print(li.xpath("./a/@href")) result = tree.xpath("/html/body/ol/li/a/@href") print(result)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    BeautifulSoup解析库

    • 安装库:pip intall bs4
    <html lang="en">
    <head>
    	<meta charset="UTF-8" />
    	<title>测试bs4</title>
    </head>
    <body>
    	<div>
    		<p>百里守约</p>
    	</div>
    	<div class="song">
    		<p>李清照</p>
    		<p>王安石</p>
    		<p>苏轼</p>
    		<p>柳宗元</p>
    		<a href="http://www.song.com/" title="赵匡胤" target="_self">
    			<span>this is span</span>
    		宋朝是最强大的王朝,不是军队的强大,而是经济很强大,国民都很有钱</a>
    		<a href="" class="du">总为浮云能蔽日,长安不见使人愁</a>
    		<img src="http://www.baidu.com/meinv.jpg" alt="" />
    	</div>
    	<div class="tang">
    		<ul>
    			<li><a href="百度一下,你就知道" title="qing">清明时节雨纷纷,路上行人欲断魂,借问酒家何处有,牧童遥指杏花村</a></li>
    			<li><a href="网易" title="qin">秦时明月汉时关,万里长征人未还,但使龙城飞将在,不教胡马度阴山</a></li>
    			<li><a href="126网易免费邮--你的专业电子邮" alt="qi">岐王宅里寻常见,崔九堂前几度闻,正是江南好风景,落花时节又逢君</a></li>
    			<li><a href="home.sina.com" class="du">杜甫</a></li>
    			<li><a href="Awesome Coming Soon Widget Responsive Widget" class="du">杜牧</a></li>
    			<li><b>杜小月</b></li>
    			<li><i>度蜜月</i></li>
    			<li><a href="http://www.haha.com" id="feng">凤凰台上凤凰游,凤去台空江自流,吴宫花草埋幽径,晋代衣冠成古丘</a></li>
    		</ul>
    	</div>
    </body>
    </html>
    
    from bs4 import BeautifulSoup
    
    #本地的html
    fp = open(r"test.html","r",encoding="utf-8")
    soup = BeautifulSoup(fp,"lxml")
    print(soup)  #返回这个网页的源代码
    print(soup.a)  #返回第一个a标签的内容
    print(soup.div) #返回第一个div 的内容
    print(soup.find("div"))  #返回第一个div 的内容
    print(soup.find("div",class_="song"))   #返回class = "song" 的div的内容
    print(soup.find_all("a"))  #返回所有a标签的内容
    print(soup.find("div",class_="song").a.get("href"))# 返回http://www.song.com/
    print(soup.find("div",class_="song").img.get("src"))#返回http://www.baidu.com/meinv.jpg
    print(soup.find("div",class_="song").a.text) # 返回文本
    print(soup.select('.tang'))   返回class = "tang" 的div的内容
    print(soup.select(".tang > ul > li > a")[0].text)   # 返回tang下的第一个标签的内容
    print(soup.select(".tang > ul > li > a")[0]['href']) # 返回tang下的第一个标签的链接
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    正则表达式

    • 正则表达式是用来简洁表达一组字符串的表达式
      在这里插入图片描述
    import re
    # 将正则表达式编译成为⼀个正则表达式对象, 规则要匹配的是3个数字
    obj = re.compile(r'\d{3}')
    # 正则表达式对象调⽤search, 参数为待匹配的字符串
    ret = obj.search('abc123eeee')
    print(ret.group()) # 结果: 123
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    元字符:具有固定含义的特殊符号 常⽤元字符:

    . 匹配除换⾏符以外的任意字符
    \w 匹配字⺟或数字或下划线
    \s 匹配任意的空⽩符 \d 匹配数字
    \n 匹配⼀个换⾏符
    \t 匹配⼀个制表符
    ^ 匹配字符串的开始 $ 匹配字符串的结尾
    \W 匹配⾮字⺟或数字或下划线
    \D 匹配⾮数字
    \S 匹配⾮空⽩符
    a|b 匹配字符a或字符b
    () 匹配括号内的表达式,也表示⼀个组
    […] 匹配字符组中的字符
    [^…] 匹配除了字符组中字符的所有字符

    量词: 控制前⾯的元字符出现的次数

    *重复零次或更多次
    +重复⼀次或更多次
    ? 重复零次或⼀次
    {n} 重复n次
    {n,} 重复n次或更多次
    {n,m} 重复n到m次

    贪婪匹配和惰性匹配

    str: 玩⼉吃鸡游戏, 晚上⼀起上游戏, ⼲嘛呢? 打游戏啊
    reg: 玩⼉.*?游戏
    此时匹配的是: 玩⼉吃鸡游戏
    reg: 玩⼉.*游戏
    此时匹配的是: 玩⼉吃鸡游戏, 晚上⼀起上游戏, ⼲嘛呢? 打游戏
    
    str: <div>胡辣汤</div>
    reg: <.*>
    结果: <div>胡辣汤</div>
    
    str: <div>胡辣汤</div>
    reg: <.*?>
    结果:
    <div>
    </div>
    
    str: <div>胡辣汤</div><span>饭团</span>
    reg: <div>.*?</div>
    结果:
    <div>胡辣汤</div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 案例:练习用正则表达式提取豆瓣电影top250的数据并保存
    # 拿到页面源代码.   requests
    # 通过re来提取想要的有效信息  re
    import requests
    import re
    import csv
    
    url = "https://movie.douban.com/top250"
    headers = {
        "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36"
    }
    resp = requests.get(url, headers=headers)
    page_content = resp.text
    
    # 解析数据
    obj = re.compile(r'
  • .*?
    .*?(?P.*?)' r'.*?

    .*?
    (?P.*?) .*? r'class="rating_num" property="v:average">(?P.*?).*?' r'(?P.*?)人评价', re.S) # 开始匹配 result = obj.finditer(page_content) f = open("data.csv", mode="w") csvwriter = csv.writer(f) for it in result: print(it.group("name")) print(it.group("score")) print(it.group("num")) print(it.group("year").strip()) dic = it.groupdict() dic['year'] = dic['year'].strip() csvwriter.writerow(dic.values()) f.close() print("over!")

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
  • cookies:处理需要登陆的网站

    headers为HTTP协议中的请求头。⼀般存放⼀些和请求内容⽆关的数据。有时也会存放⼀些安全验证信息,比如常⻅的User-Agent,cookies等。通过requests发送的请求, 我们可以把请求头信息放在headers中。也可以单独进⾏存放, 最终由requests⾃动帮我们拼接成完整的http请求头

    selenium

    Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,Selenium 可以直接调用浏览器,它支持所有主流的浏览器(包括PhantomJS这些无界面的浏览器),可以接收指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏等

    • 在下载好chromedriver以及安装好selenium模块后,可以执行下列代码并观察运行的过程
    from selenium import webdriver 
    # 如果driver没有添加到了环境变量,则需要将driver的绝对路径赋值给executable_path参数
    # driver = webdriver.Chrome(executable_path='driver的绝对路径')
    
    # 如果driver添加了环境变量则不需要设置executable_path
    driver = webdriver.Chrome()
    # 向一个url发起请求
    driver.get("https://www.baidu.com/")
    # 把网页保存为图片
    driver.save_screenshot("baidu.png")
    # 打印页面的标题
    print(driver.title) 
    # 在百度搜索框中搜索'python'
    driver.find_element_by_id('kw').send_keys('python')
    # 点击'百度搜索'
    driver.find_element_by_id('su').click()
    # 退出模拟浏览器
    driver.quit()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • selenium工作原理:利用浏览器原生的API,封装成一套更加面向对象的Selenium WebDriver API,直接操作浏览器页面里的元素,甚至操作浏览器本身(截屏,窗口大小,启动,关闭,安装插件,配置证书之类的)
    • 在selenium中可以通过多种方式来定位标签,返回标签元素对象
    find_element_by_id                         (返回一个元素)
    find_element(s)_by_class_name             (根据类名获取元素列表)
    find_element(s)_by_name                 (根据标签的name属性值返回包含标签对象元素的列表)
    find_element(s)_by_xpath                 (返回一个包含元素的列表)
    find_element(s)_by_link_text             (根据连接文本获取元素列表)
    find_element(s)_by_partial_link_text     (根据链接包含的文本获取元素列表)
    find_element(s)_by_tag_name             (根据标签名获取元素列表)
    find_element(s)_by_css_selector         (根据css选择器来获取元素列表)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • selenium获取cookie:driver.get_cookies()返回列表,其中包含的是完整的cookie信息!不光有name、value,还有domain等cookie其他维度的信息。所以如果想要把获取的cookie信息和requests模块配合使用的话,需要转换为name、value作为键值对的cookie字典
    # 获取当前标签页的全部cookie信息
    print(driver.get_cookies())
    # 把cookie转化为字典
    cookies_dict = {cookie[‘name’]: cookie[‘value’] for cookie in driver.get_cookies()}
    
    • 1
    • 2
    • 3
    • 4
    • selenium控制浏览器执行js代码
    import time
    from selenium import webdriver
    
    driver = webdriver.Chrome()
    driver.get("http://www.itcast.cn/")
    time.sleep(1)
    
    js = 'window.scrollTo(0,document.body.scrollHeight)' # js语句
    driver.execute_script(js) # 执行js的方法 跳转到最底部
    
    time.sleep(5)
    driver.quit()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    scrapy框架

    • Scrapy是一个Python编写的开源网络爬虫框架。它是一个被设计用于爬取网络数据、提取结构性数据的框架
      在这里插入图片描述
    • scrapy的架构如下图,图中中文是为了方便理解后加上去的。图中绿色线条的表示数据的传递。注意图中中间件的位置,决定了其作用。注意其中引擎的位置,所有的模块之前相互独立,只和引擎进行交互
      在这里插入图片描述
    • 爬虫中起始的url构造成request对象–>爬虫中间件–>引擎–>调度器
    • 调度器把request–>引擎–>下载中间件—>下载器
    • 下载器发送请求,获取response响应---->下载中间件---->引擎—>爬虫中间件—>爬虫
    • 爬虫提取url地址,组装成request对象---->爬虫中间件—>引擎—>调度器,重复步骤2
    • 爬虫提取数据—>引擎—>管道处理和保存数据

    scrapy的三个内置对象

    • request请求对象:由url method post_data headers等构成
    • response响应对象:由url body status headers等构成
    • item数据对象:本质是个字典

    scrapy中每个模块的具体作用
    在这里插入图片描述

  • 相关阅读:
    EMC VNX支持数据文件说明
    基于yolov5的交通标志牌的目标检测研究设计——思路及概念
    AODNet复现: 用gpu批量处理图片
    【Leetcode】212.单词搜索II(Hard)
    2023年,消失的金三银四
    JavaWeb——Servlet原理、生命周期、IDEA中实现一个Servlet(全过程)
    【Shopee热销选品】新加坡、马来西亚市场最新时装配饰类目
    jQuery【事件处理器、鼠标事件、表单事件、键盘事件、浏览器事件、事件对象、jQuery遍历】(三)-全面详解(学习总结---从入门到深化)
    docker私有仓库registry
    2019我的Java面试跳槽经历
  • 原文地址:https://blog.csdn.net/Listennnn/article/details/136661430