Python爬虫基础操作二

目录

四、爬虫数据存储csv/excel

五、session与cookies

六、selenium库:控制浏览器操作

七、定时与邮件


上一篇爬虫操作基础,本篇讲解爬虫数据存储、cookies,session,以及浏览器自动操作工具selenium

爬虫操作比较完整的步骤如下图所示:

总体上来说,从Response对象开始,我们就分成了两条路径,一条路径是数据放在HTML里,所以我们用BeautifulSoup库去解析数据和提取数据;另一条,数据作为Json存储起来,所以我们用response.json()方法去解析,然后提取、存储数据。

四、爬虫数据存储csv/excel

csv为python自带模块,无需安装。

csv基本操作步骤:

打开文件——>读取数据/写入数据——>关闭文件

示例如下:

# CSV存储示例
import csv
with open('test.csv','a', newline='',encoding='utf-8') as f:
    writer  = csv.writer(f)
#['4', '猫砂', '25', '1022', '886']
#['5', '猫罐头', '18', '2234', '3121']
    writer.writerow(['4', '猫砂', '25', '1022', '886'])
    writer.writerow(['5', '猫罐头', '18', '2234', '3121'])
# CSV读取示例   
with open('test.csv','r', newline='',encoding='utf-8') as f:
    read = csv.reader(f)
    for row in read:
        print(row)

excel操作可以使用openpyxl,为第三方库,需按照:pip install openpyxl 

Excel文件写入步骤:

1、创建工作簿:利用openpyxl.Workbook()创建workbook对象;

2、获取工作表:借助workbook对象的avtive属性;

3、操作单元格:单元格:sheet['A1'];一行:append();

4、保存工作簿:save().

# xlsx表格存储示例
from openpyxl import Workbook

wb = Workbook()    #建立工作簿
ws = wb.active
ws.title    #打印title
# ‘Sheet’
ws.title = 'python'    #改变sheet title
ws.title
# 'python'
ws2 = wb.create_sheet('java')    #新建工作表
ws2.title
# 'java'
wb.sheetnames
# ['python','java']
ws['E1'] = 111    #向E1单元写入数据
ws.cell(row=2,column=2,value=222)    #向第二行第二列的单元格写入数据
# <Cell 'python'.B2>
wb.save('example.xlsx')    #保存excel表格

五、session与cookies

1、session与cookies联系

session和cookies的关系还非常密切——cookies中存储着session的编码信息,session中又存储了cookies的信息。

当浏览器第一次访问购物网页时,服务器会返回set cookies的字段给浏览器,而浏览器会把cookies保存到本地。

等浏览器第二次访问这个购物网页时,就会带着cookies去请求,而因为cookies里带有会话的编码信息,服务器立马就能辨认出这个用户,同时返回和这个用户相关的特定编码的session。

流程如下图所示:

 

cookies和session的关系如此密切,那我们可以通过创建一个session来处理cookies。

 

 

计算机之所以需要cookies和session,是因为HTTP协议是无状态的协议。

何为无状态?就是一旦浏览器和服务器之间的请求和响应完毕后,两者会立马断开连接,也就是恢复成无状态。

这样会导致:服务器永远无法辨认,也记不住用户的信息,像一条只有7秒记忆的金鱼。是cookies和session的出现,才破除了web发展史上的这个难题。

cookies不仅仅能实现自动登录,因为它本身携带了session的编码信息,网站还能根据cookies,记录你的浏览足迹,从而知道你的偏好,只要再加以推荐算法,就可以实现给你推送定制化的内容。

2、post请求:

post和get都可以带着参数请求,不过get请求的参数会在url上显示出来。但post请求的参数就不会直接显示,而是隐藏起来。像账号密码这种私密的信息,就应该用post的请求。如果用get请求的话,账号密码全部会显示在网址上。可以这么理解,get是明文显示,post是非明文显示。

通常,get请求会应用于获取网页数据,比如我们之前学的requests.get()。post请求则应用于向网页提交数据,比如提交表单类型数据(像账号密码就是网页表单的数据)。

【requests headers】存储的是浏览器的请求信息,【response headers】存储的是服务器的响应信息

 

 一般post操作重点:

1、post带着参数地请求登录;

2、获得登录的cookies;

3、带cookies去请求发送信息;

3、cookies存储与提取

1) cookies

 

cookies转化成字典的方法

  • requests.utils.dit_from_cookieday(cj)
  • 从CookieJar返回键/值字典。
  • 参数: cj - 从中提取cookie的CookieJar对象。
  • 返回类型:字典

requests对于cookies格式的转化,提供了三个工具方法:

requests.utils.dict_from_cookiejar(cj)
Returns a key/value dictionary from a CookieJar.
Parameters: cj – CookieJar object to extract cookies from.


requests.utils.cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True)
Returns a CookieJar from a key/value dictionary.
Parameters: 

    cookie_dict – Dict of key/values to insert into CookieJar.
    cookiejar – (optional) A cookiejar to add the cookies to.
    overwrite – (optional) If False, will not replace cookies already in the jar with new ones.


requests.utils.add_dict_to_cookiejar(cj, cookie_dict)
Returns a CookieJar from a key/value dictionary.
Parameters: 

    cj – CookieJar to insert cookies into.
    cookie_dict – Dict of key/values to insert into CookieJar.

json模块的使用方法:

  • json为第三方库,安装: pip install json
  • json.dumps() 将Python对象编码成JSON字符串。
  • json.loads() 将已编码的JSON字符串解码为Python对象。

但都是cookiejar和字典格式之间的转换,并没有几种cookies格式相互的转换,所以我是以字典为中间格式进行转换的。

2)读取cookies

在这里我用的是LWPCookieJar保存在txt文件中

#实例化一个LWPCookieJar对象
load_cookiejar = cookielib.LWPCookieJar()
#从文件中加载cookies(LWP格式)
load_cookiejar.load('cookies/' + self.username + '.txt', ignore_discard=True, ignore_expires=True)
#工具方法转换成字典
load_cookies = requests.utils.dict_from_cookiejar(load_cookiejar)
#工具方法将字典转换成RequestsCookieJar,赋值给session的cookies.
self.session.cookies = requests.utils.cookiejar_from_dict(load_cookies)

 

3)存储cookies

将cookies转换成LWP格式然后保存为文本格式

 

#实例化一个LWPcookiejar对象
new_cookie_jar = cookielib.LWPCookieJar(self.username + '.txt')

#将转换成字典格式的RequestsCookieJar(这里我用字典推导手动转的)保存到LWPcookiejar中
requests.utils.cookiejar_from_dict({c.name: c.value for c in self.session.cookies}, new_cookie_jar)

#保存到本地文件
new_cookie_jar.save('cookies/' + self.username + '.txt', ignore_discard=True, ignore_expires=True)

4)完整示例

import requests, json
session = requests.session()
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36'}

def cookies_read():
    cookies_txt = open('cookies.txt', 'r')
    cookies_dict = json.loads(cookies_txt.read())
    cookies = requests.utils.cookiejar_from_dict(cookies_dict)
    return (cookies)
    # 以上4行代码,是cookies读取。

def sign_in():
    url = ' https://wordpress-edu-3autumn.localprod.oc.forchange.cn/wp-login.php'
    data = {'log': input('请输入你的账号'),
            'pwd': input('请输入你的密码'),
            'wp-submit': '登录',
            'redirect_to': 'https://wordpress-edu-3autumn.localprod.oc.forchange.cn',
            'testcookie': '1'}
    session.post(url, headers=headers, data=data)
    cookies_dict = requests.utils.dict_from_cookiejar(session.cookies)
    cookies_str = json.dumps(cookies_dict)
    f = open('cookies.txt', 'w')
    f.write(cookies_str)
    f.close()
    # 以上5行代码,是cookies存储。


def write_message():
    url_2 = 'https://wordpress-edu-3autumn.localprod.oc.forchange.cn/wp-comments-post.php'
    data_2 = {
        'comment': input('请输入你要发表的评论:'),
        'submit': '发表评论',
        'comment_post_ID': '13',
        'comment_parent': '0'
    }
    return (session.post(url_2, headers=headers, data=data_2))
    #以上9行代码,是发表评论。

try:
    session.cookies = cookies_read()
except FileNotFoundError:
    sign_in()

num = write_message()
if num.status_code == 200:    #解决cookies过期的问题,如果过期则重新登入
    print('成功啦!')
else:
    sign_in()
    num = write_message()
    print(num.status_code)

六、selenium库:控制浏览器操作

selenium是什么呢?它是一个强大的Python库。

它可以做什么呢?它可以用几行代码,控制浏览器,做出自动打开、输入、点击等操作,就像是有一个真正的用户在操作一样。

selenium操作步骤:

 

1、安装selenium

pip install selenium

2、下载谷歌浏览器chrome,安装对应版本浏览器驱动ChromeDriver

https://www.google.cn/intl/zh-CN/chrome/

http://npm.taobao.org/mirrors/chromedriver/

https://localprod.pandateacher.com/python-manuscript/crawler- html/chromedriver/ChromeDriver.html

3、浏览器设置

 

# 本地Chrome浏览器设置方法(打开一个真实的浏览器界面)
from selenium import webdriver #从selenium库中调用webdriver模块
driver = webdriver.Chrome() # 设置引擎为Chrome,真实地打开一个Chrome浏览器

# 本地Chrome浏览器的静默默模式设置(不显示浏览器界面,后台运行):
from selenium import  webdriver #从selenium库中调用webdriver模块
from selenium.webdriver.chrome.options import Options # 从options模块中调用Options类

chrome_options = Options() # 实例化Option对象
chrome_options.add_argument('--headless') # 把Chrome浏览器设置为静默模式
driver = webdriver.Chrome(options = chrome_options) # 设置引擎为Chrome,在后台默默运行

4、selenium数据提取

BeautifulSoup解析网页源代码,然后提取其中的数据。

selenium库同样也具备解析数据、提取数据的能力。它和BeautifulSoup的底层原理一致,但在一些细节和语法上有所出入selenium所解析提取的,是Elements中的所有数据,而BeautifulSoup所解析的则只是Network中第0个请求的响应。

使用BeautifulSoup解析提取数据时,首先要把Response对象解析为BeautifulSoup对象,然后再从中提取数据。

而在selenium中,获取到的网页存在了driver中,而后,解析与提取是同时做的,都是由driver这个实例化的浏览器完成,解析数据是由driver自动完成的,提取数据是driver的一个方法。

selenium解析与提取数据的过程中,我们操作的对象转换:

 

selenium可以获取到渲染完整的网页源代码。

使用driver的一个方法:page_source

HTML源代码字符串 = driver.page_source 

用requests.get()获取到的是Response对象,在交给BeautifulSoup解析之前,需要用到.text的方法才能将Response对象的内容以字符串的形式返回。

而使用selenium获取到的网页源代码,本身已经是字符串了。可以直接交给BeautifulSoup进行解析。

 

5、selenium自动操作浏览器

 

完整示例:

# 本地Chrome浏览器设置方法
from selenium import  webdriver #从selenium库中调用webdriver模块
import time
from bs4 import BeautifulSoup

driver = webdriver.Chrome() # 设置引擎为Chrome,真实地打开一个Chrome浏览器
#driver是浏览器驱动的实例化对象
driver.get('https://localprod.pandateacher.com/python-manuscript/hello-spiderman/') 
time.sleep(2)

#操作浏览器
# teacher = driver.find_element_by_id('teacher')
# teacher.send_keys('必须是吴枫呀')
# assistant = driver.find_element_by_name('assistant')
# assistant.send_keys('都喜欢')
# time.sleep(1)
# button = driver.find_element_by_class_name('sub')
# time.sleep(1)
# button.click()
# time.sleep(1)
# driver.close()

# 提取出网页 你好,蜘蛛侠! 中所有label标签中的文字
#方法一:
# labels = driver.find_elements_by_tag_name('label')
# labels = BeautifulSoup.find_all('label')
# for label in labels:
#     print(label.text)
# driver.close()
#方法二:selenium + BeautifulSoup
html = driver.page_source
html_soup = BeautifulSoup(html,'html.parser')
labels = html_soup.find_all('label')
for label in labels:
    print(label.text)
driver.close()
#刷新页面
import time
from selenium import webdriver

driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(6)

driver.get("https://www.baidu.com")
time.sleep(2)
try:
driver.refresh() # 刷新方法 refresh
print ('test pass: refresh successful')
except Exception as e:
print ("Exception found", format(e))
driver.quit()

Selenium是一个强大的网络数据采集工具,它的优势是简单直观,而它当然也有缺点。由于是真实地模拟人操作浏览器,需要等待网页缓冲的时间,在爬取大量数据的时候,速度会比较慢。通常情况,在爬虫项目中,selenium都是用在其它方法无法解决,或是很难解决的问题时,才会用到。

当然,除了爬虫,selenium的使用场景还有很多。比如:它可以控制网页中图片文件的显示、控制CSS和JavaScript的加载与执行等等。

七、定时与邮件

1、邮件发送步骤:

2、定时

关于时间,其实Python有两个内置的标准库——time和datetime(我们在基础课也学过time.sleep())。

但在这里,我们不准备完全依靠标准库来实现,而准备选取第三方库——schedule。

标准库一般意味着最原始最基础的功能,第三方库很多是去调用标准库中封装好了的操作函数。比如schedule,就是用time和datetime来实现的。

完整示例:

#@ description  :爬虫+邮件定时发送实战:定时发送天气信息
#               自动爬取每日的天气,并定时把天气数据和穿衣提示发送到你的邮箱
#               http://www.weather.com.cn/weather/101280601.shtml
#@ Author       :Dannie
#@ time         :2020/08/09 23:02:02
#@ version      :V1.0
#********************#

import requests
import smtplib
import schedule
import time
from bs4 import BeautifulSoup
from email.mime.text import MIMEText
from email.header import Header

account = input('请输入你的邮箱:')
password = input('请输入你的密码:')
receiver = input('请输入收件人的邮箱:')

def weather_spider():
    headers={'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'}
    url='http://www.weather.com.cn/weather/101280601.shtml'
    res=requests.get(url,headers=headers)
    res.encoding='utf-8'
    soup=BeautifulSoup(res.text,'html.parser')
    tem1= soup.find(class_='tem')
    weather1= soup.find(class_='wea')
    tem=tem1.text
    weather=weather1.text
    return tem,weather

def send_email(tem,weather):
    mailhost='smtp.qq.com'
    qqmail = smtplib.SMTP()
    qqmail.connect(mailhost,25)
    qqmail.login(account,password)
    content= tem+weather
    message = MIMEText(content, 'plain', 'utf-8')
    subject = '今日天气预报'
    message['Subject'] = Header(subject, 'utf-8')
    try:
        qqmail.sendmail(account, receiver, message.as_string())
        print ('邮件发送成功')
    except:
        print ('邮件发送失败')
    qqmail.quit()

def job():
    print('开始一次任务')
    tem,weather = weather_spider()
    send_email(tem,weather)
    print('任务完成')

schedule.every().day.at("07:30").do(job) 
while True:
    schedule.run_pending()
    time.sleep(1)

 

 

 

 

 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值