第十讲 Python爬虫

爬虫是用浏览器访问的方式,模拟了访问网站的过程。
包括的三个阶段及对应工具:
(1)打开网页:用Requests访问页面,得到服务器返回的数据,包括HTML页面以及JSON数据。
(2)提取数据:针对HTML页面,使用XPath进行元素定位,提取数据;针对JSON数据,使用JSON进行解析。
(3)保存数据:使用Pandas保存数据,最后导出CSV文件。

Requests访问页面

Requests是Python HTTP的客户端库。有两种访问方式:Get和Post。Get把参数包含在url中,而Post通过request body来传递参数。
首先 安装requests包
在这里插入图片描述

在这里插入图片描述
用r.text 或 r.content获取HTML正文
在这里插入图片描述

XPath定位

XPath是XML的路径语言,通过元素和属性进行导航,定位位置。
几种常用的路径表达方式:
在这里插入图片描述
使用XPath定位,用到解析库lxml.
在这里插入图片描述

JSON对象

Python对象与JSON对象进行转换,使数据解析更加方便。
Python转换成JSON:json.dumps()
JSON转换成Python: json.loads()
在这里插入图片描述

实战:用Python抓取海报

(1)通过JSON数据爬取
首先把日常操作步骤整理下来:
1、打开网页;
2、输入关键词“王祖贤”
3、在搜索结果页中选择图片
4、下载图片页中的所有海报

若爬取页面为动态页面,需要关注XHR数据。因为动态页面的原理就是通过原生的XHR数据对象发出HTTP请求,得到服务器返回的数据后,在进行处理。XHR会用于在后台与服务器交换数据。
在浏览器中按F12进入开发者模式,选择网络中的XHR项,重新加载页面。如下图所示,类型为json。
在这里插入图片描述
复制右侧的目标url网址,在浏览器中打开,就得到我们想要的图片数据了。
在这里插入图片描述
从这个JSON对象中,可以看出,王祖贤的图片一共有22598张,一次返回20张。数据放在了images对象中,是一个数结构,每个数组的元素是个字典类型,分别告诉了src(原图片地址), author(作者), url(发布地址), id(图片ID), title(标题), width(图片宽度), height(图片高度)字段:
在这里插入图片描述

然后,寻找XHR请求的url规律:https://www.douban.com/j/search_photo?q=王祖贤&limit=20&start=20 在这个网址中,有三个参数:q, limit和start。
start是请求的起始ID,是从0开始计算的,start为20就表示从21张图片开始下载。

下载图片的具体代码如下:

import requests
import json
query='王祖贤'
def download(src,id):
    dir='./'+str(id)+'.jpg' #./表示当前路径,../表示上一级路径
    try:
        pic=requests.get(src,timeout=10) #获取图片
    except requests.exceptions.ConnectionError:
            print('图片无法下载')
    fp=open(dir,'wb') #打开写入到dir路径,一般常用模式:r(只读)、w(只写)、a(追加)、b(二进制)
    fp.write(pic.content)#content返回类型为二进制数据, open文件用wb
    fp.close()
for i in range(0,22598,20):
    url='https://www.douban.com/j/search_photo?q='+query+'&limit=20&start='+str(i)
    html=requests.get(url).text
    response=json.loads(html,encoding='utf-8') #json转换成python
    for image in response['images']:
        print(image['src'])
        download(image['src'],image['id'])

(2)通过XPath自动下载海报
日常下载步骤:
1、打开网页https://movie.douban.com/
2、输入关键词“王祖贤”
3、下载图片页中的所有电影海报

我们需要用XPath定位图片网址,以及电影名称。
XPath可以不受加载的限制,定位到想要的元素。
用google浏览器的XPath Helper插件,按住ctrl+shift+x快捷键,鼠标放到想要定位的元素,就会得到如下类似结果:
在这里插入图片描述
该插件有两个参数:Query中输入XPath语法,然后在Results里看到匹配元素的结果。
要匹配到所以的电影海报,就要缩减XPath表达式
所有电影海报的XPath:
在这里插入图片描述
所有电影名称的XPath:
在这里插入图片描述

需用Selenium库进行网页加载的模拟,加载完成后,得到完整的HTML。
Selenium是Web应用的测试工具,可以直接运行在浏览器中,原理是模拟用户进行操作。当然使用之前,先要安装Selenium包:
在这里插入图片描述
用Selenium库模拟打开Chrome浏览器访问目标页面:

from selenium import webdriver
driver = webdriver.Chrome(executable_path = 'C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe')
driver.get("https://movie.douban.com/subject_search?search_text=%E7%8E%8B%E7%A5%96%E8%B4%A4&cat=1002")

这里WebDriver库是用于Web应用程序的自动测试工具,方便操作。通过WebDriver创建一个Chrome浏览器的driver,再通过driver获取访问页面的完整HTML。获取HTML后,可以对其中的XPath进行提取,在这里,需要图片地址srcs和电影名称titles。完整代码如下:

def download(src,id):
    dir='../'+str(id)+'.webp' #这里图片为webp格式
    try:
        pic=requests.get(src,timeout=10)
    except requests.exceptions.ConnectionError:
            print('图片无法下载')
    fp=open(dir,'wb') #以二进制格式打开一个文件只用于写入。
    fp.write(pic.content)
    fp.close()
from lxml import etree #XPath定位用到解析库lxml
from selenium import webdriver
driver = webdriver.Chrome(executable_path = 'C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe')
driver.get("https://movie.douban.com/subject_search?search_text=%E7%8E%8B%E7%A5%96%E8%B4%A4&cat=1002")
html=etree.HTML(driver.page_source)#
srcs=html.xpath("//div[@class='item-root']/a[@class='cover-link']/img[@class='cover']/@src")
titles=html.xpath("//div[@class='item-root']/div[@class='detail']/div[@class='title']/a[@class='title-text']")
for src,title in zip(srcs,titles): #zip(A,B)两个列表合并成一个元组列表
    print(src)
    download(src,title.text)

总结:

在这里插入图片描述

自练:
将豆瓣电影网站上热门前100的电影海报信息进行爬取,并写入excel表格的代码

import pandas as pd
from pandas import Series,DataFrame
import json
import requests
def download(cover,title):
    dir="./"+title+".jpg"
    try:
        pic=requests.get(cover,timeout=10)
    except requests.exceptions.ConnectionError:
        print("Error!")
    fp=open(dir,'wb')
    fp.write(pic.content)
    fp.close()
result=pd.DataFrame(columns=['cover','cover_x','cover_y','id','is_new','playable','rate','title','url'])# 建立空的DataFrame
for i in range(0,100,20):
    url='https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start='+str(i)
    html=requests.get(url).text
    response=json.loads(html,encoding='utf-8')
    for image in response['subjects']:
#        download(image['cover'],image['title'])
        d=Series(image)
        result=result.append(d,ignore_index=True)
        #以上还可以写成 d=DataFrame(image,index=[image['title']]); result=result.append(d),索引为title
print(result)
score=DataFrame(result)
score.to_excel('top_movie.xlsx') 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值