爬虫高级

Day05笔记*****************************

1、json模块

  1、什么是json?(数据传输的格式)
    javascript中的对象和数组
    对象 :{key:value}  取值:对象名.key
    数组 :[...,...]	取值:数组[索引值]
  2、作用
    json格式的字符串 和 Python数据类型 之间的转换
  3、常用方法
    1、json.loads() : json格式 --> Python数据类型
              json      python
			对象  ——>   字典
			数组  ——>   列表
  			见 01_json.loads示例.py
    2、json.dumps() : Python数据类型 --> json格式
	              python       json
					字典         对象
					列表         数组
					元组         数组
	      ## 注意
	        1、json.dumps()在序列化时默认使用ascii编码
			2、添加参数ensure_ascii=False,表示禁用ascii编码
'''01_json.loads实例'''
import json

#json格式的数组
jsarray = '[1,2,3,4]'
#数组->列表
L = json.loads(jsarray)
print(type(L),L)

#json格式对象
jsobj = '{"city":"天地会","name":"步惊云"}'
#对象->字典
D = json.loads(jsobj)
print(type(D),D)

结果:
在这里插入图片描述

"""
Created on Wed Sep 18 23:48:05 2019

@author: aa
"""
'''02_json.dumps实例'''
import json

L = [1,2,3,4]
T = (1,2,3,4)
D = {"city":"天地会","name":"逆风"}
#python格式 ->json格式
jsarry1 = json.dumps(L)
print(type(jsarry1),jsarry1)

jsarry2 = json.dumps(T)
print(type(jsarry2),jsarry2)

jsaobj = json.dumps(D,ensure_ascii = False)
print(type(jsaobj),jsaobj)

在这里插入图片描述

2、动态网站数据抓取 - Ajax

1、特点 :滚动鼠标滑轮时加载
2、案例 :豆瓣电影排行榜数据抓取
1、抓取目标 :豆瓣电影 - 排行榜 - 剧情
电影名称 、评分
2、代码实现

'''03_豆瓣电影抓取-Ajax.py'''
import requests
import json
import csv

# url要写抓到的GET :URL
url = "https://movie.douban.com/j/chart/top_list?"
headers = {"User-Agent":"Mozilla/5.0"}
num = input("请输入要爬取的数量:")
params = {
        "type":"11",
        "interval_id":"100:90",
        "action":"",	
        "start":"0",
        "limit":num
    }

res = requests.get(url,params=params,headers=headers)
res.encoding = "utf-8"
# html为json格式的数组[{电影1信息},{},{}]
html = res.text
# 数组 -> 列表
html = json.loads(html)
# 用for循环遍历每一个电影信息{}
for film in html:
    name = film['title']
    score = film["rating"][0]
    #{"rating":["9.6","50"],...}
    with open("豆瓣电影.csv","a",newline="") as f:
        writer = csv.writer(f)
        L = [name,score]
        writer.writerow(L)

这里需要注意的就是这个使用get的url,因为我的Fiddler 无法安装证书,所以拿不到get的url,这个url是老师上课讲的。

'''03_豆瓣电影抓取-Ajax.py'''
import requests
import json
import csv

# url要写抓到的GET :URL
url = "https://movie.douban.com/j/chart/top_list?"
headers = {"User-Agent":"Mozilla/5.0"}
L = ["剧情","喜剧","动作"]
tp_list = [{"剧情":"11"},{"喜剧":"24"},{"动作":"5"}]
tp = input("请输入电影类型:")

if tp in L:
    num = input("请输入要爬取的数量:")
    for film_dict in tp_list:
        for key,value in film_dict.items():
            if tp == key:
                params = {
                        "type":value,
                        "interval_id":"100:90",
                        "action":"",	
                        "start":"0",
                        "limit":num
                    }
                
                res = requests.get(url,params=params,headers=headers)
                res.encoding = "utf-8"
                # html为json格式的数组[{电影1信息},{},{}]
                html = res.text
                # 数组 -> 列表
                html = json.loads(html)
                # 用for循环遍历每一个电影信息{}
                for film in html:
                    name = film['title']
                    score = film["rating"][0]
                    #{"rating":["9.6","50"],...}
                    with open("豆瓣电影.csv","a",newline="") as f:
                        writer = csv.writer(f)
                        L = [name,score]
                        writer.writerow(L)
else:
    print("您输入的类型不存在!")

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

3、selenium + phantomjs 强大的网络爬虫组合

1、selenium

1、定义 :Web自动化测试工具,应用于Web自动化测试
2、特点
  1、可以运行在浏览器,根据指定命令操作浏览器,让浏览器自动加载页面
  2、只是工具,不是浏览器,不支持浏览器功能,需要与第三方浏览器结合使用

2、phantomjs

1、定义 :无界面浏览器(无头浏览器)
2、特点
  1、把网站加载到内存进行页面加载
  2、运行高效
3、安装
  1、Windows
    1、将下载的可执行文件放到Python安装目录的Scripts目录下
  C:\Python36\Scripts
  安装:
  chromedriver.exe
  phantomjs.exe
  2、Ubuntu
    1、将下载的phantomjs放到一个路径下
	2、添加环境变量:
	  vi .bashrc 添加
	  export PHANTOM_JS=/home/.../phantomjs-2.1.1-...
	  export PATH=$PHANTOM_JS/bin:$PATH
	  终端:source .bashrc
	  终端:phantomjs

我在phantomjs官网上无法下载phantomjs.exe,所以就没有安装,只是安装了chromedriver.exe

3、示例代码

1、示例代码1 : 见05_phantomjs+selenium示例1.py

'''05_phantomjs+selenium示例1.py'''
from selenium import webdriver
#创建一个chromjs浏览器对象
driver = webdriver.Chrome()
#发请求
driver.get("http://www.baidu.com/")
#获取响应的html源码
print(driver.page_source)
#获取网页截屏
driver.save_screenshot("百度.png")
#print("图片保存成功")
##关闭
driver.quit()

在这里插入图片描述

2、示例代码2 : 见06_phantomjs+selenium示例2.py
# -*- coding: utf-8 -*-
"""
Created on Fri Sep 20 00:01:39 2019

@author: aa
"""

#06_phantomjs+selenium示例2.py
from selenium import webdriver
import time
#创建浏览器对象
driver = webdriver.Chrome()

#打开页面
driver.get("http://www.baidu.com/")

#发送文字到搜索框
kw = driver.find_element_by_id("kw")
kw.send_keys("易烊千玺")

#点击“百度一下”
su = driver.find_element_by_id("su")
su.click()
time.sleep(1)
#获取截屏
driver.save_screenshot("千玺.png")

#关闭浏览器
driver.quit()

这个很好玩,你什么都不用干,感觉浏览器可以听懂你的话,搜索—>百度一下—>保存图片
在这里插入图片描述
大佬的图片就是赏心悦目

4、常用方法

1、driver.get(url)
2、driver.page_source : 获取响应的html源码(有用)
3、driver.page_source.find("字符串")
  1、作用 :从html源码中搜索指定字符串
     -1	   :查找失败
	非-1   :查找成功
4、单元素查找
  1、driver.find_element_by_id("").text(获取节点里面的文本内容)
  2、driver.find_element_by_class_name("")
  3、driver.find_element_by_xpath('xpath表达式')
  4、如果匹配到多个节点,则只返回第1个节点对象
5、多元素查找
  1、driver.find_elements_by_....
  2、注意
    1、如果结果1个,则返回节点对象,不是列表
	2、如果结果N个,则返回列表,;列表里的每个对象就是节点元素
  3、示例见 :08_driver.find查找元素示例.py
6、对象名.send_keys("内容")
7、对象名.click()

5、案例1 :登录豆瓣网站

见 :09_selenium+Chrome登陆豆瓣案例.py
# -*- coding: utf-8 -*-
"""
Created on Fri Sep 20 19:35:05 2019
09_selenium+Chrome登陆豆瓣案例
@author: aa
"""
from selenium import webdriver
import time
#创建浏览器对象,发请求
driver = webdriver.Chrome()
driver.get("https://www.douban.com/")
time.sleep(0.5)
#获取截图(验证码)
driver.save_screenshot("验证码.png")

#找用户名、密码、验证、登录豆瓣按钮
#用户名
uname = driver.find_element_by_name("form_email")
uname.send_keys("*****")#这里虽然写的是通过email,但我输入自己的手机号同样可以成功登录,不可思议,但是存在一个问题。
#密码
pwd = driver.find_element_by_name("form_password")
pwd.send_keys("******")#这个就是自己注册的登录密码
#验证码
key = input("请输入验证码:")#验证码会发到手机上
yzm = driver.find_element_by_id("captcha_field")
yzm.send_keys(key)
driver.save_screenshot("完成.png")
#点击登录按钮
login = driver.find_element_by_class_name("bn-submit")
login.click()
time.sleep(1)
driver.save_screenshot("登录成功.png")
#关闭浏览器
driver.quit()

现在来说说我存在的那个问题,虽然能成功登录,但是却无法除了验证码的图片,我无法保存其他的图片,而且还报了下面这个错误
在这里插入图片描述

6、操作键盘

1、导模块
  from selenium.webdrier.common.keys import Keys
2、常用方法
  见 :10_driver操作键盘示例.py
# -*- coding: utf-8 -*-
"""
Created on Fri Sep 20 19:58:34 2019
10_driver操作键盘示例.py
@author: aa
"""
from selenium import webdriver
#操作键盘
from selenium.webdriver.common.keys import Keys
import time
#创建浏览器对象,发请求
driver = webdriver.Chrome()
driver.get("http://www.baidu.com/")
#百度搜索框输入python
kw = driver.find_element_by_id("kw")
kw.send_keys("python")
driver.save_screenshot("01_python.png")

#全选: Ctrl + a
kw = driver.find_element_by_id("kw")
kw.send_keys(Keys.CONTROL,'a')
driver.save_screenshot("02_ctrlA.png")

#剪切: Ctrl + x
kw = driver.find_element_by_id("kw")
kw.send_keys(Keys.CONTROL,'x')
driver.save_screenshot("03_ctrlX.png")

#粘贴: Ctrl + v
kw = driver.find_element_by_id("kw")
kw.send_keys(Keys.CONTROL,'v')
driver.save_screenshot("04_ctrlV.png")
 #清空搜索框:对象名.clear()
kw = driver.find_element_by_id("kw")
kw.clear()
driver.save_screenshot("05_clear.png")
 #输入:万里
kw = driver.find_element_by_id("kw")
kw.send_keys("万里")
driver.save_screenshot("06_tarena.png")
 
 #输入:回车
kw = driver.find_element_by_id("kw")
kw.send_keys(Keys.ENTER)
time.sleep(1)
driver.save_screenshot("07_enter.png")
#关闭浏览器
driver.quit()
 

这个代码页很好玩,就像变魔术一样

7、案例2 :斗鱼直播网站主播信息抓取(JS分页加载)

代码见 :11_斗鱼直播抓取案例.py
1、抓取目标 :主播名称 、观众人数
  1、主播 :class -> dy-name ellipsis fl
    //div[@id="live-list-content"]//span[@class="dy-name ellipsis fl"]

  2、人数 :class -> dy-num fr
    //div[@id="live-list-content"]//span[@class="dy-num fr"]

  3、下一页按钮(能点) :class -> shark-pager-next
  4、下一页按钮(不能点)
    class -> shark-pager-next shark-pager-disable shark-pager-disable-next
'''11_斗鱼直播抓取案例.py'''
from selenium import webdriver
from lxml import etree
import time

# 把Chrome设置无界面浏览器
opt = webdriver.ChromeOptions()
opt.set_headless()
# 创建浏览器对象,发请求
driver = webdriver.Chrome(options=opt)
driver.get("https://www.douyu.com/directory/all")
i = 1

# 循环
while True:
    # 解析(driver.page_source)
    # 获取主播名称 和 观众人数
    parseHtml = etree.HTML(driver.page_source)
    names = parseHtml.xpath('//div/h2[@class="DyListCover-user"]')
    numbers = parseHtml.xpath('//div/span[@class="DyListCover-hot"]')
    
    for name,number in zip(names,numbers):
        print("\t主播名称:%s \t观众人数:%s" % (name.text.strip(),number.text.text.strip()))
        #for name,number in [("主播1","20万"),("主播2","15万")]
    print("第%d页爬取成功" % i)
    i += 1
    # 判断是否需要点击下一页
    # 能点 :点击,继续循环
    if driver.page_source.find("dy-Pagination-disabled dy-Pagination-next") == -1:
        driver.find_element_by_class_name("dy-Pagination-next").click()
        time.sleep(2)
    else:
        break
    # 不能点 :break

print("一共爬取了%d页" % i)

在这里插入图片描述
一直报这个错,但我已经检查好几遍了,还是没弄懂是什么原因。

8、Chromdriver如何设置无界面模式

1、opt = webdriver.ChromeOptions()
2、opt.set_headless()
3、driver = webdriver.Chrome(options=opt)
4、driver.get(url)

9、案例3 :京东商品爬取

1、目标
  1、商品名称
  2、商品价格
  3、评论数量
  4、商家名称
2、代码实现
# -*- coding: utf-8 -*-
"""
Created on Sat Sep 21 10:01:54 2019
12_京东商品爬取
@author: aa
"""
from selenium import webdriver
import time
import csv

#接受用户输入,访问京东
pro = input("请输入要爬取的商品:")
driver = webdriver.Chrome()
driver.get("https://www.jd.com/")
#发送文字到搜索框,点击搜索
text = driver.find_element_by_class_name('text')
text.send_keys(pro)

button = driver.find_element_by_class_name('button')
button.click()
time.sleep(1)
i = 1
while True:
    #动态加载--->全部加载
    #执行脚本,进度条拉到底部
    driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')
    time.sleep(2)
    
    #正常解析爬取
    r_list = driver.find_elements_by_xpath('//div[@id="J_goodsList"]//li')
    #r为每一个商品的节点对象
    for r in r_list:
        m = r.text.split('\n')
        #["$52.80","Python...","200+"]
        price = m[0]
        name = m[1]
        commit = m[2]
        market = m[3]
        
        with open("商品.csv","a",newline= "",encoding= "gb18030") as f:
            writer = csv.writer(f)
            L = [name.strip(),price.strip(),commit.strip(),market.strip()]
            writer.writerow(L)
            
    break

    print("第%d页爬取成功" % i)
    i += 1
    
    #点击下一页


在这里插入图片描述
虽然爬到了,但我的为什么和老师的差别这么大,有点奇怪。

# -*- coding: utf-8 -*-
"""
Created on Sat Sep 21 21:04:28 2019
13_京东商品爬取优化
@author: aa
"""
from selenium import webdriver
import time
import csv

#接受用户输入,访问京东
pro = input("请输入要爬取的商品:")
driver = webdriver.Chrome()
driver.get("https://www.jd.com/")
#发送文字到搜索框,点击搜索
text = driver.find_element_by_class_name('text')
text.send_keys(pro)

button = driver.find_element_by_class_name('button')
button.click()
time.sleep(1)
i = 1
while True:
    #动态加载--->全部加载
    #执行脚本,进度条拉到底部
    driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')
    time.sleep(2)
    
    #正常解析爬取
    r_list = driver.find_elements_by_xpath('//div[@id="J_goodsList"]//li')
    #r为每一个商品的节点对象
    for r in r_list:
        m = r.text.split('\n')
        #["$52.80","Python...","200+"]
        price = m[0]
        name = m[1]
        commit = m[2]
        market = m[3]
        
        with open("商品.csv","a",newline= "",encoding= "gb18030") as f:
            writer = csv.writer(f)
            L = [name.strip(),price.strip(),commit.strip(),market.strip()]
            writer.writerow(L)
            
    

    print("第%d页爬取成功" % i)
    i += 1
    
    #点击下一页
    if driver.page_source.find("pn-next disable") == -1:
        driver.find_element_by_class_name("pn-next").click()
        time.sleep(1)
    else:
        print("抓取结束,共抓取%d页"% i)
        

这个是爬取多页的代码。
在这里插入图片描述
在这里插入图片描述
突然觉得樱木的名字好好听,樱花,木道,感觉给他起名字的这个人是一个很温暖的人。
Day06笔记********************************************

1、多线程爬虫

1、进程线程回顾

1、进程
  1、系统中正在运行的一个应用程序
  2、1个CPU核心1次只能执行1个进程,其他进程处于非运行状态
  3、N个CPU核心可同时执行N个任务
2、线程
  1、进程中包含的执行单元,1个进程可包含多个线程
  2、线程可使用所属进程空间(但1次只能执行1个线程,阻塞)
  3、锁 :防止多个线程同时使用共享空间
3、GIL :全局解释锁
 程序 执行的通行证,谁拿到,谁就可以使用Python解释器,仅此1个,拿到了通行证可执行,否则 等
4、应用场景
  1、多进程:大量的密集的计算
  2、多线程:I/O密集
    爬虫 :网络I/O--->多线程
写文件:本次磁盘I/O--->多线程

2、案例 :使用多线程爬取 百思不得其姐 段子

1、爬取目标 :段子内容
2、URL :http://www.budejie.com/
3、xpath表达式 
  //div[@class="j-r-list-c-desc"]/a/text()
4、知识点
  1、队列(from queue import Queue)
    put()
    get()
   Queue.empty() :是否为空
   Queue.join()  :如果队列为空,执行其他程序
  2、线程(import threading)
    threading.Thread(target=...)
5、代码实现 
  见 :01_多线程爬取百思不得其姐案例.py
# -*- coding: utf-8 -*-
"""
Created on Sat Sep 21 22:20:00 2019
01_使用多线程爬取 百思不得其姐 段子
@author: aa
"""
from lxml import etree
import requests
from queue import Queue
import threading
import time
class bsSpider:
    def __init__(self):
        self.baseurl = "http://www.budejie.com/"
        self.headers = {"User-Agent":"Mozilla/5.0"}
        #存放url的队列
        self.urlQueue = Queue()
        #存放响应的队列
        self.resQueue = Queue()
    #生成存放url的队列
    def getUrl(self):
        for pNum in range(1,51):
            #拼接url
            url = self.baseurl + str(pNum)
            #将url放到队列里
            self.urlQueue.put(url)
    
    #响应队列
    def getHtml(self):
        #写成死循环,一直从url里取url
        while True:
            url = self.urlQueue.get()
            res = requests.get(url,headers = self.headers)
            res.encoding = "utf-8"
            html = res.text
            #放到响应队列
            self.resQueue.put(html)
            #清除此任务
            self.urlQueue.task_done()
    
    #解析页面
    def getContent(self):
       while True:
           #从响应队列中依次获取响应源码
           html = self.resQueue.get()
           parseHtml = etree.HTML(html)
           r_list = parseHtml.xpath('//div[@class="j-r-list-c-desc"]/a/text()')
           for r in r_list:
               print(r + "\n")
        
           #清除任务
           self.resQueue.task_done()
               
        
    def run(self):
        #存放所有的线程
        thread_list = []
        #产生url队列
        self.getUrl()
        #创建getHtml线程
        for i in range(1):
            theadRes = threading.Thread(target = self.getHtml)
            thread_list.append(theadRes)
        #创建解析的线程   
        for i in range(1):
            threadParse = threading.Thread(target=self.getContent)
            thread_list.append(threadParse)
        
        #所有线程开始干活
        for th in thread_list:
            #守护线程(都没有听过)
            th.setDaemon(True)
            th.start()
            
        #如果队列为空,则执行其他线程
        self.urlQueue.join()
        self.resQueue.join()
        print("运行结束")
            
            
            
    
if __name__ == "__main__":
    begin = time.time()
    spider = bsSpider()
    spider.run()
    end = time.time()
    print(end - begin)

虽然老师讲的很清楚,但我觉得我还是不会用

2、BeautifulSoup

1、定义

HTML或XML的解析器,依赖于lxml

2、安装

python -m pip install beautifulsoup4
导模块:
  from bs4 import BeautifulSoup

3、使用流程

1、导入模块
  from bs4 import BeautifulSoup
2、创建解析对象 
  soup = BeautifulSoup(html,'lxml')
3、查找节点对象
  soup.find_all(name="属性值")

4、示例代码 :见 02_BeautifulSoup示例.py

"""
Created on Sat Sep 21 23:24:40 2019
02_BeautifulSoup示例
@author: aa
"""
from bs4 import BeautifulSoup

html = '<div id = "test">柯南</div>'

#创建解析对象
soup = BeautifulSoup(html,'lxml')

#查找节点
r_list = soup.find_all(id = "test")
#print(r_list)
for r in r_list:
    print(r.get_text())

结果:柯南

5、BeautifulSoup支持的解析库

1、lxml         :BeautifulSoup(html,'lxml')
    特点:速度快,文档容错能力强
2、python标准库 :BeautifulSoup(html,'html.parser')
    特点: 速度一般
3、xml解析器    :BeautifulSoup(html,'xml')
    特点: 速度快,文档容错能力强

6、节点选择器

1、选择节点
  soup.节点名 :soup.a、soup.ul
2、获取文本内容
  soup.节点名.string

7、常用方法

1、find_all() :查询所有符合条件的元素,返回列表
  1、r_list = soup.find_all(属性名="属性值")
     r_list = soup.find_all(class_="test")
  2、r_list=soup.find_all("节点名",attrs={"名":"值"})
     r_list=soup.find_all("div",attrs={"class":"test"}
# -*- coding: utf-8 -*-
"""
Created on Sat Sep 21 23:24:40 2019
03_BeautifulSoup升华
@author: aa
"""
from bs4 import BeautifulSoup

html = '<div class = "test">柯南</div>'

#创建解析对象
soup = BeautifulSoup(html,'lxml')

#查找节点
r_list = soup.find_all(id = "test")
r_list = soup.find_all("div",attrs = {"class":"test"})

for r in r_list:
    print(r.get_text())
# -*- coding: utf-8 -*-
"""
Created on Sat Sep 21 23:48:24 2019
04_BeautifulSoup实例再升华
@author: aa
"""
from bs4 import BeautifulSoup
html = '''<div class = "test">柯南</div>
        <div class = "test">小兰</div>
        <div class = "test2">
            <span>伦敦</span>
        </div>
        '''
#创建解析对象
soup = BeautifulSoup(html,"lxml")      
#找class为test的div的文本内容
divs = soup.find_all("div",attrs = {"class":"test"})
for div in divs:
    #print(div.string)(法1)
    print(div.get_text())
        
#找class为test2的div下的span中文本内容
divs = soup.find_all("div",attrs = {"class":"test2"})
for div in divs:
    print(div.span.string)


结果:
柯南
小兰
伦敦
最近柯南看到他们去伦敦了

"""
Created on Sun Sep 22 00:02:56 2019
05_糗事百科BeautifulSoup
@author: aa
"""
from bs4 import BeautifulSoup
import requests
url = "https://www.qiushibaike.com/"
headers = {"User-Agent":"Mozilla/5.0"}

res = requests.get(url,headers = headers)
res.encoding = "utf-8"
html = res.text

#创建解析对象
soup = BeautifulSoup(html,"lxml")
r_list = soup.find_all("div",attrs = {"class":"content"})

for r in r_list:
    s = r.span.get_text().strip()
    print(s)
    print("*" * 30 )

由于我做的时候“糗事百科”的服务器正在升级,所以没有验证,但老师是弄出来了的。

3、Scrapy框架安装(Ubuntu)

1、安装依赖库

sudo apt-get install python3-dev build-essential libssl-dev libffi-dev liblxml2 libxml2-dev libxslt1-dev zlib1g-dev

2、升级pyasn1模块

sudo pip3 install pyasn1==0.4.4

3、安装Scrapy

sudo pip3 install Scrapy

windows:直接在Anaconda Prompt 里输入conda install Scrapy

4、Scrapy框架

1、Scrapy框架

异步处理框架,可配置和可扩展程度非常高,Python中使用最广泛的爬虫框架

2、框架组成

1、引擎(Engine) :整个框架核心
2、调度器(Scheduler) :接受从引擎发过来的URL,入队列
3、下载器(Downloader):下载网页源码,返回给爬虫程序
4、项目管道(Item Pipeline) :数据处理
5、下载器中间件(Downloader Middlewares)
  处理引擎与下载器之间的请求与响应
6、蜘蛛中间件(Spider Middlerwares)
  处理爬虫程序输入响应和输出结果以及新的请求
7、Item :定义爬取结果的数据结构,爬取的数据会被赋值为Item对象

3、Scrapy框架的爬取流程

见 Scrapy框架流程.png
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190922094401147.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0JUWnl3bA==,size_16,color_FFFFFF,t_70)

文字描述:
、运行流程
1、Engine开始统揽全局,向Spider索要URL
2、Engine拿到url后,给Scheduler入队列
3、Schduler从队列中拿出url给Engine,通过Downloader Middlewares给Downloader去下载
4、Downloader下载完成,把response给Engine
5、Engine把response通过Spider Middlewares给Spider
6、Spider处理完成后,
把数据给Engine,交给Item Pipeline处理,
把新的URL给Engine,重复2-6步
7、Scheduler中没有任何Requests请求后,程序结束

4、制作Scrapy爬虫项目步骤

1、新建项目
  scrapy startproject 项目名
2、明确目标(items.py)
3、制作爬虫程序
  XXX/spiders :scrapy genspider 文件名 域名
4、处理数据(pipelines.py)
5、配置settings.py
6、运行爬虫项目
  scrapy crawl 爬虫名

5、scrapy项目文件详解

1、目录结构
testspider/
├── scrapy.cfg   #项目基本配置文件,不用改
└── testspider
    ├── __init__.py
    ├── items.py       # 定义爬取数据的结构
    ├── middlewares.py # 下载器中间件和蜘蛛中间件实现
    ├── pipelines.py   # 处理数据
    ├── settings.py    # 项目全局配置
    └── spiders        # 存放爬虫程序
		├── __init__.py
		├── myspider.py
2、settings.py配置
  # 是否遵守robots协议,改为False
  ROBOTSTXT_OBEY = False

  # 最大并发量,默认为16个
  CONCURRENT_REQUESTS = 32

  # 下载延迟时间为3秒
  DOWNLOAD_DELAY = 3

  # 请求报头
  DEFAULT_REQUEST_HEADERS = {
    'User-Agent': "Mozilla/5.0",
     'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
     'Accept-Language': 'en',
    }

  # 蜘蛛中间件
  SPIDER_MIDDLEWARES = {
     'testspider.middlewares.TestspiderSpiderMiddleware': 543,
    }

  # 下载器中间件
  DOWNLOADER_MIDDLEWARES = {
     'testspider.middlewares.TestspiderDownloaderMiddleware': 543,
    }

  # 管道文件
  ITEM_PIPELINES = {
     'testspider.pipelines.TestspiderPipeline': 300,
  }
3、示例 :抓取百度首页源码,存到baidu.html中(Linixu中,因为我没有这个环境,所以就没有实践)
  1、scrapy startproject baidu
  2、cd baidu/baidu
  3、subl items.py(此示例可不用操作)
  4、cd spiders
  5、scrapy genspider baiduspider baidu.com
    # 爬虫名
	# 域名
	# start_urls
	def parse(self,response):
    	with open("baidu.html","w") as f:
        	f.write(response.text)
  6、subl settings.py
    1、关闭robots协议
	2、添加Headers
 7、cd spiders
 8、scrapy crawl baiduspider

5、pycharm运行scrapy项目

1、创建文件 begin.py

和scrapy.cfg同目录
from scrapy import cmdline
cmdline.execute("scrapy crawl baiduspider".split())

2、在

Run -> Editconfigurations -> + -> python
name : spider
Script : begin.py的路径
working directory : 你自己的项目路径

3、打开begin.py

右上角 -> 点 运行

Day07笔记******************************************

1、生成器

1、yield作用 :把一个函数当做一个生成器使用
2、斐波那契数列 Fib.py
3、yield特点 :让函数暂停,等待下一次调用

2、项目 :Csdn

1、知识点 yield 、pipelines.py
2、目标
1、https://blog.csdn.net/devcloud/article/details/101024677
2、标题、发表时间、阅读数
3、步骤
1、创建项目
2、定义数据结构(items.py)
3、创建爬虫程序
4、第3步抓取的数据通过项目管道去处理
5、全局配置
6、运行爬虫程序
这个scrapy框架就像之前的Danjo框架,今天快要把我搞死了,幸好有各路大神的帮助,我才写出了第一个scrapy项目。现在来仔细说一下我今天的创建项目的过程。
首先,在windows上安装scrapy就花了我好长时间,最后还说没有弄出来,让一个大佬帮忙弄出来的,代价就是我的C盘又快炸了。
他帮我弄好之后我却不能创建scrapy项目,又百度了很长时间,在我快要放弃的时候,大佬给我个建议,不要在Anaconda 的Python的环境里面创建scrapy项目,我就试着在自己安装的python3.7里面创建了项目,果然能行。
在这里插入图片描述
然后就是在Terminal里面创建项目了,只要出现这个界面就是成功了。我当时激动的要飞起。
在这里插入图片描述
然后cd到项目下,我看老师讲的是还要cd到spiders,但我弄不到,就试着进行下面的操作了。我知道我后面为啥不跟老师的一样了,我还得再往下走一层,应该是Csdn/Csdn/,在创建爬虫文件的,怪不得我导入模块的时候报错,原来是这里的问题。(我又来补充了,我做下面那个项目的时候,跟着老师做的,但是还是不能导入,还是要根据大佬的from …才能出来)
在这里插入图片描述
在这里插入图片描述
出现了和老师一样的目录,于是我就接着听下去了。
在这里插入图片描述
最后运行项目,终于出来杰伦的《说好不哭》了,再不出来我真的要哭了。
在这里插入图片描述
但其实我做这个的时候还是遇到了一个bug,就是我明明在我要在csdn.py里面导入items.py的CsdnItem模块,但它就是报错,后来我一气之下,想,不就是几个变量嘛,老子大不了直接在csdn.py里面写,我就把items.py里的
在这里插入图片描述
直接复制到csdn.py里面了,这次就对了,但老师是用“from Csdn.items import ScdnItem”也没有报错,为什么我的就报错,百思不得其解。
https://blog.csdn.net/mr_muli/article/details/80161028
看了这个大佬的解释,我的就可以导入了,他也知识改成了“from …items import CsdnItem”,(是两个点,不知道为什么我明明点的两个,但显示出来的却是三个,大家看不懂的话,还是看大佬的吧)原谅我一个Liniux入门的小白,不懂这些是为什么,但这样也解决问题了,感谢大佬们帮我这个小白。
在这里插入图片描述
果然,想当小白也不是那么容易的,我现在要创建下一个项目了,所以想回到Day7,但跟着老师写cd Csdn 竟然回不去,又只能百度找大佬了,cd …
原来这样就能回去呢。

3、项目 :Daomu

1、URL :http://www.daomubiji.com/dao-mu-bi-ji-1
http://www.daomubiji.com/qi-xing-lu-wang-01.html
2、目标
书名、书的标题、章节名称、章节数量、章节链接
3、步骤
1、创建项目 Daomu
2、改items.py(定义数据结构)
3、创建爬虫文件
4、改pipelines.py(项目管道文件)
5、配置settings.py
6、运行爬虫
做这个项目的时候就顺利多了,本来想把我Terminal里面的命令截图出来的,但运行完之后,可能是行数太多,之前的都没有了,哎,好不容易想好好表现一次,还不让我表现了,其实就是跟着老师写,其中不同的一点就是导items中的模块那里,我还是用了上面那个大佬的方法。妈妈的,今天学得手都酸了。

4、知识点

1、extract() : 获取选择器对象中的文本内容
# response.xpath(’…’) 得到选择器对象(节点所有内容) [<selector …,data=…>’]
# response.xpath(’…/text()’) 得到选择器对象(节点文本) [<selector …,data=‘文本内容’>]
# extract() : 把选择器对象中的文本取出来 [‘文本内容’]
2、爬虫程序中的 start_urls必须为列表
start_urls = []
3、pipelines.py中必须有个函数叫 process_item(self,item,spider),当然还可以写任何其他函数

5、存入MongoDB数据库

1、在settings.py中定义相关变量
MONGODB_HOST =
MONGODB_PORT =
2、可在pipelines.py中新建一个class
from Daomu import settings
(from . import settings)
class DaomumongoPipeline(object):
def init(self):
host = settings.MONGODB_HOST
3、在settings.py文件中设置你的项目管道
ITEM_PIPELINES = {
“Daomu.pipelines.DaomumongoPipeline”:100,
}
今天最开心的就是学会了Mongo,老师没有教我们,我跟着教程做的,之前有安装,但是不知道自己有没有装好,这次终于做出来了。原来在Terminal这里也可以打开mongo
在这里插入图片描述
在这里插入图片描述
这里我只贴出了怎么使用mongo,只是针对我自己的情况,还有我发现点击那个“+”号就可以再有一个新的界面

6、存入MySQL数据库

1、self.db.commit()
天天,我今天学到了好多呀,原来Terminal命令行也可以到mysql呀,我的天,我感觉我之前的日子都白活了。
在这里插入图片描述
在这里插入图片描述
一个激动忘记打逗号了。
在这里插入图片描述
看到数据库中的存入之后想回到原来的路径,但是我这个小白还是不会,所以我使用了最简单粗暴的方法,点击“+”号,又从最简单的开始,cd之类的,然后也成功了。看来小白还是有活路的。

7、Csdn项目存到mongodb和mysql

2019/9.23 9.54
昨天晚上的东西动都没动,今天运行就不可以了,我要被气死了,怎么可以这样对我,我的《盗墓笔记》,我的《说好不哭》,我做到12点半,还要我怎样
2019/9.23 16.13
在这里插入图片描述
早上出不来,下午就出来了,果然写代码不能心急。
在这里插入图片描述
好了,现在mongo和mysql里都存了《说好不哭》了。好开心。

8、腾讯招聘网站案例

1、URL
第1页:https://hr.tencent.com/position.php?&start=0
现在:https://careers.tencent.com/search.html?index=0
第2页:https://hr.tencent.com/position.php?&start=10
现在:https://careers.tencent.com/search.html?index=2
2、Xpath匹配
基准xpath表达式(每个职位节点对象)
//tr[@class=“even”] | //tr[@class=“old”]
现在://div[@class = “recruit-list”]
职位名称 : ./td[1]/a/text()现在://h4/text()
详情链接 : ./td[1]/a/@href
职位类别 : ./td[2]/text()现在://div//p/span[3]
招聘人数 : ./td[3]/text()
工作地点 : ./td[4]/text()现在://div//p/span[2]
发布时间 : ./td[5]/text()现在://div//p/span[4]
爬不了了,感觉是因为改版之后,我的和老师的一样,但就是爬取不到,放弃挣扎了。
在这里插入图片描述
是的,我就是这么一个容易放弃的人,算了,如果哪位大佬这样爬取成功了,麻烦告诉我一声,感谢。
不过我知道了怎么存到csv文件里面,首先注释settings.py里面的
在这里插入图片描述
然后在Terminal终端输入

scrapy crawl tengxun -o zhaopin.csv

就可以了,加油。

Day08笔记****************************************************

1、如何设置随机User-Agent

1、settings.py(少量User-Agent切换,不推荐)

1、定义USER_AGENT变量值
2、DEFAULT_REQUEST_HEADER={"User-Agent":"",}

2、设置中间件的方法来实现

1、项目目录中新建user_agents.py,放大量Agent
  user_agents = ['','','','','']
2、middlewares.py写类:
  from 项目名.user_agents import user_agents
  import random
  class RandomUserAgentMiddleware(object):
     def process_request(self,request,spider):
   request.headers["User-Agent"] = random.choice(user_agents)
   注意这个headers,老师上课的时候都没想到,还是学生提出来的

3、设置settings.py
  DOWNLOADER_MIDDLEWARES = {
    "项目名.middlewares.RandomUserAgentMiddleware" : 1}

3、直接在middlewares.py中添加类

class RandomUserAgentMiddleware(object):
    def __init__(self):
    self.user_agents = ['','','','','','']
def process_request(self,request,spider):
    request.header['User-Agent'] = random.choice(self.user_agents)

2、设置代理(DOWNLOADER MIDDLEWARES)

1、middlewares.py中添加代理中间件ProxyMiddleware

class ProxyMiddleware(object):
    def process_request(self,request,spider):
        request.meta['proxy'] = "http://180.167.162.166:8080"

2、settings.py中添加

DOWNLOADER_MIDDLEWARES = {
   'Tengxun.middlewares.RandomUserAgentMiddleware': 543,
   'Tengxun.middlewares.ProxyMiddleware' : 250,
}
抱歉,这里我没有弄出来,可能是国庆期间太严了吧,换了几个代理都不行。

3、图片管道 :ImagePipeline

1、使用流程(要操作的文件)

1、settings.py
  设置图片要保存的路径的变量
  IMAGES_STORE = "/home/tarena/aaa/aaa/images"
2、pipelines.py
  1、导入scrapy定义好的图片管道类
    from scrapy.pipelines.images import ImagesPipeline
  2、定义自己的class,继承scrapy的图片管道类
    class AAAImagePipeline(ImagesPipeline):
       def get_media_requests(self,item,info):
        ... ... 

2、案例 :斗鱼图片抓取案例(手机app)

1、菜单 --> 颜值
  http://capi.douyucdn.cn/api/v1/getVerticalRoom?limit=20&offset=0
2、抓取目标
  1、图片链接
  2、主播名
  3、城市
    把所有图片保存在 IMAGES_STORE
3、步骤
  1、前提 :手机和电脑一个局域网
  2、Fiddler抓包工具
    Connections : Allow remote computers to ..
HTTPS : ...from all processes
  3、IP地址 :Win+r -> cmd -> ipconfig
  4、配置手机
    手机浏览器 :http://IP:8888
下载 FiddlerRoot certificate
  5、安装
    设置 -> 更多 -> ... -> 从存储设备安装
  6、设置手机代理
    长按 wifi,->代理
IP地址 :
端口号 :
4、项目实现
跟着老师一起做,成功了,只是我没有自己在手机上实验,因为我的手机内存不够了,

4、dont_filter参数

scrapy.Request(url,callback=…,dont_filter=False)
dont_filter参数 :False->自动对URL进行去重
True -> 不会对URL进行去重

我把这个用在“腾讯招聘”的那个项目里面,还是出不来

5、Scrapy对接selenium+phantomjs

1、创建项目 :Jd
2、middlewares.py中添加selenium
1、导模块 :from selenium import webdriver
2、定义中间件
class seleniumMiddleware(object):

def process_request(self,request,info):
# 注意:参数为request的url
self.driver.get(request.url)
3、settings.py
DOWNLOADER_MIDDLEWARES={“Jd.middleware.seleniumMiddleware”:20}
虽然获取到了,但是和老师的还是有点区别,就是我的一直在循环输入,哎,不搞了,今天要累死了,明天接着看

加进来的:爬取西刺代理ip,筛选出哪些ip可用

这个是老师没讲过的,但是布置了作业,所以我打算自己做一下。没想到建表的时候就要死翘翘了。
在这里插入图片描述
首先是建表。建完之后我想查看一下有没有建对,可是我竟然忘记了,万能的百度又帮了我的大忙。
在这里插入图片描述
原来只要这样就可以了。
这个我暂时还没有做出来,原来自己做的时候真的很难呢。

6、Scrapy模拟登陆

1、创建项目 :Renren
2、创建爬虫文件
我跟着老师做到是做出来了,但是html文档有中文乱码的情况,还不知道怎么解决。先接着往下看一下。

7、机器视觉与tesseract

1、OCR(Optical Character Recognition)光学字符识别
扫描字符 :通过字符形状 --> 电子文本,OCR有很多的底层识别库
2、tesseract(谷歌维护的OCR识别开源库,不能import,工具)
1、安装
1、windows下载安装包
https://sourceforge.net/projects/tesseract-ocr-alt/files/tesseract-ocr-setup-3.02.02.exe/download
安装完成后添加到环境变量
2、Ubuntu : suo apt-get install tesseract-ocr
3、Mac : brew install tesseract
2、验证
终端 :tesseract test1.jpg text1.txt
3、安装pytesseract模块
python -m pip install pytesseract
windows:pip install pytesseract
在这里插入图片描述
老师给的应该是在Linux里面安装的,但是在windows里面就直接pip就可以了。
# 方法很少,就用1个,图片转字符串:image_to_sting
4、Python图片的标准库
from PIL import Image
5、示例
1、验证码图片以wb方式写入到本地
2、image = Image.open(“验证码.jpg”)
3、s = pytesseract.image_to_string(image)
这个做出来了。
在这里插入图片描述
6、tesseract案例 :登录豆瓣网站
在这里插入图片描述
这个案例我的一直没有出来,不知道是不是因为豆瓣改版了,现在没有图形的验证码了,只有发送到手机的验证码,所以我是照着老师的写的xpath语句,没有取到。

8、分布式介绍

1、条件

1、多台服务器(数据中心、云服务器)
2、网络带宽

2、分布式爬虫方式

1、主从分布式
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190924203000924.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0JUWnl3bA==,size_16,color_FFFFFF,t_70)

2、对等分布式

3、scrapy-redis

重写scrapy调度器里面的方法,实现了所有服务器过来爬取都不可能重复的功能
2019/9/24 20.43
首先给自己鼓掌,经历这么久的时间,终于把爬虫过了一遍了,虽然还是很多东西学了就忘了,我自己的脑子我自己清楚,哎,算了,但是我总算是学完了,还有一些小bug,我还没有弄出来,不知道以后会不会再回过头来看。

  • 3
    点赞
  • 1
    评论
  • 12
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

包小彤

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值