python爬虫入门实例

基础

anaconda管理

activate
conda env list 
activate my-rdkit-env

常用库

在这里插入图片描述

路径

双斜杠转义字符:

savepath = ".\\abc.xls"

HTTP常用的方法

在这里插入图片描述
HTTP与HTTPS的测试网站:

httpbin.org

STEP1:爬取网页

关于response的几种形态

response.text 返回文本(爬网站html)
response.json() 返回的是字典或者列表对象
response.content 返回的是二进制形式的响应数据(爬取图片等)

基于urllib库

获取一个get请求

需要对获取的网页源码进行utf-8的解码

response = urllib.request.urlopen("http://www.baidu.com");
print(response.read().decode("utf-8"));
获取一个post请求

post请求需要本地先提交表单信息:

import urllib.parse;
data = bytes(urllib.parse.urlencode({"a":"b"}),encoding = "utf-8");
response = urllib.request.urlopen("http://www.httpbin.org/post",data = data);
print(response.read().decode("utf-8"));
伪造User-Agent

如果出现https无法解析,换一个python interpreter

import ssl;
url = "https://www.douban.com"
headers = {
	"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36"
}
req = urllib.request.Request(url=url,headers=headers);
response = urllib.request.urlopen(req);
print(response.read().decode("utf-8"));

基于requests库

requests库更加方便,所以建议采用这个库

爬取sougou.com

在这里插入图片描述

爬取搜狗搜索页面-Get请求

在这里插入图片描述

import sys
import ssl
import urllib
import requests

if __name__ == "__main__":
    # url = "https://www.sogou.com/web?query="
    url = "https://www.sogou.com/web"
    param = {
        'query' : 'red velvet'
    }
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'
    }
    response = requests.get(url=url,params=param,headers=headers)
    pagetext = response.text

    with open('./sougou.html',"w",encoding="utf-8") as fp: #文件的写操作
        fp.write(pagetext);
    print("yes!");
爬取百度翻译页面-Post请求

在这里插入图片描述

import sys
import ssl
import urllib
import requests
import json

if __name__ == "__main__":
    # url = "https://www.sogou.com/web?query="
    url = "https://fanyi.baidu.com/sug"
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'
    }
    data = {
        'kw' :'dog'
    }
    response = requests.post(url=url,data=data,headers=headers)
    pagetext = response.json()

    with open('./sougou.html',"w",encoding="utf-8") as fp: #文件的写操作
        json.dump(pagetext,fp);
    print("yes!");
爬取豆瓣电影排行榜-Get请求

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

爬取药监局页面
import sys
import ssl
import urllib
import requests
import json
import re
if __name__ == "__main__":
    url = "http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList"
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'
    }
    for i in range(1,10):
        data = {
            'on': 'true',
            'page': str(i),
            'pageSize': '15',
            'productName': ' ',
            'conditionType': '1',
            'applyname': " ",
            'applysn': " "
        }
        response = requests.post(url=url,headers=headers)
        pagetext = response.json()
        #抓取所有id
        idlist = [];
        for item in pagetext["list"]:
            # print("item:",item);
            idlist.append(item['ID']);

    #获取各个子网页
    pagetexts = []
    sonurl = "http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById"
    for id in idlist:
        sondata = {
            'id':id
        }
        sonresponse = requests.post(url = sonurl,data=sondata,headers=headers);
        pagetexts.append(sonresponse.json())
    # print(pagetexts)

    with open('./sougou.html',"w",encoding="utf-8") as fp: #文件的写操作
        json.dump(pagetexts,fp);
        # fp.write(pagetext)
    print("yes!");
模拟登陆后爬取
验证码识别

基于线上的打码平台:1. 超级鹰(可以识别12306) 2. 云打码 3. 打码兔

流程

  1. 对验证码图片进行捕获和识别
    这里用的云打码,打码平台需要将图片先下载到本地再解析,先get请求到图片的src,再下载到本地
page_text = requests.get(url=url,headers=headers).text;

tree = etree.HTML(page_text);
src = "https://so.gushiwen.org" + tree.xpath('')[0]; #观察发现,定位到的src还需加上源地址
#保存图片数据到本地
img_data = requests.get(src,headers=headers).content; 
with open('./code.jpg','wb') as fp:
	fp.write(imgdata);
#调用识别平台的API即可
  1. post请求发送(模拟登陆)
    发现失败,改用session,成功
  2. 验证是否成功/永久存储返回的文件

人人网登陆实例:
在这里插入图片描述
在这里插入图片描述

cookie操作

处理方法
方式1. (非建议)手动cookie:通过抓包工具获得cookie值,手动封装到headers

headers = {
	'cookie':'XXXX'
}

方式2. 自动cookie:session对象会自动保存产生的cookie

session = requests.Session();
response = session.post(url=aurl,headers=headers,data=data); #session对象请求post,模拟登陆aurl
session.get(url=burl,headers=headers);#获取burl的信息
请求的data里存在动态变化的参数

处理方法
方式1. 该参数会隐藏在前台页面,例如github的csrf-token参数
方式2. 基于抓包工具全局搜索,找到对应的数据包

梨视频爬取实例:参考该博客
难点1:网站存在反爬机制,需要在头文件里加referer参数
难点2:视频的链接地址是js加载的,需要向其发起get请求得到视频源地址
难点3:视频源地址打不开,需要拼接得到最后的url

import requests
import urllib
import json
import re
import lxml
import os
from lxml import etree
dirname = 'piclib'
if not os.path.exists(dirname):
    os.mkdir(dirname)
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36",
}

session = requests.Session()
def pa():

    url = "https://www.pearvideo.com/category_130"
    req = session.get(url=url,headers=headers);
    page_text = req.text;
    # print(page_text)

    #xpath获取最热视频的链接
    det_urls = []
    tree = etree.HTML(page_text)
    det_urls = tree.xpath('//div[@class="category-top"]//li//a[@class="vervideo-lilink actplay"]/@href')
    for i in range(0,3):
        det_url = "https://www.pearvideo.com/" + det_urls[i]
        contId = det_urls[i].replace('video_',"");
        # print(det_url)
        # !! Referer参数防反爬
        det_headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36",
            "Referer": str(det_url),
        }
        video_page_json = session.get(url = "https://www.pearvideo.com/videoStatus.jsp?contId="+contId,headers=det_headers).json()
        video_url = video_page_json['videoInfo']['videos']['srcUrl']
        # print(video_url)

        suffix = video_url.split('-')[1]
        date = video_url.split('/')[-2]
        new_url = 'https://video.pearvideo.com/mp4/adshort/{}/cont-{}-{}-ad_hd.mp4'.format(date, contId, suffix)
        # return

pa()

STEP2:解析数据

html相关基础

HTML 标签对大小写不敏感。

  • 标题(Heading)是通过<h1>-<h6>等标签进行定义
    <h1> 定义最大的标题,<h6>定义最小的标题。
  • 段落是通过 <p> 标签进行定义
  • 链接是通过 <a> 标签进行定义
  • 图像是通过 <img> 标签进行定义
  • 注释是通过<!-- This is a comment -->进行定义
  • 在不产生一个新段落的情况下进行换行(新行),使用 <br /> 标签

CSS相关基础

  • 可用CSS选择器进行查找
  • 样式表:当浏览器读到样式表时,它将根据样式表中的信息来格式化 HTML 文档。
  1. 外部CSS
    每张 HTML 页面必须在 head 部分的 <link> 元素内包含对外部样式表文件的引用。
    外部样式表可以在任何文本编辑器中编写,并且必须以 .css 扩展名保存。
    外部 .css 文件不应包含任何 HTML 标签。
  2. 内部CSS
    如果一张 HTML 页面拥有唯一的样式,那么可以使用内部样式表。
    内部样式是在 head 部分的 <style> 元素中进行定义。
  3. 行内CSS
    行内样式(也称内联样式)可用于为单个元素应用唯一的样式。
    如需使用行内样式,请将 style 属性添加到相关元素。style 属性可包含任何 CSS 属性。
<!DOCTYPE html>
<html>
<body>

<h1 style="color:blue;text-align:center;">This is a heading</h1>
<p style="color:red;">This is a paragraph.</p>

</body>
</html>
  • 使用 <div> 元素的 HTML 布局
    <div> 元素常用作布局工具,因为能够轻松地通过 CSS 对其进行定位。

解析内容

使用BeautifulSoup定位特定标签
使用正则表达式找到具体内容

标签解析:BeautifulSoup模块

解析原理:
1. 实例化一个beautifulSoup对象,且将待解析的数据加载到该对象中
2. 调用bs对象中相关方法或者属性进行标签定位和文本数据的提取
实例化的方法
1. bs = BeautifulSoup(html,“lxml”);
2. bs = BeautifulSoup(html,“html.parser”);

#提前安装lxml解析器或者parser解析器
file = open("","rb");
html = file.read();
bs = BeautifulSoup(html,"lxml");
# bs = BeautifulSoup(html,"html.parser"); #实例化一个bs对象,且将待解析的数据加载到该对象中
item = bs.find_all("div",class_="item");#调用bs对象中相关方法或者属性进行标签定位和文本数据的提取
  • 打印标签 print(bs.title)
  • 打印标签直系文字内容 print(bs.title.string)
  • 打印标签所有文字内容 XXX.text
  • BeautifulSoup类,打印整个文档
  • 注释,输出无注符号的注释
soup = BeautifulSoup(html,"html.parser");
items = soup.find_all("div",class_="col l4 m6 s12 channel-list-item")
正则提取:re模块

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

import re
response = requests.get('XXXX');
pagetext = response.text;
findimg = r'xxxxxx' 
img_list = re.findall(findimg,pagetext,Re.S) #Re.S忽略换行,返回的是list
findlink = re.compile(r'<a href="(.*?)">'); #查找括号里的内容
findimg = re.compile(r'<img.*src="(.*?)".*/>');
img = re.findall(findimg,item)[0];
findBD = re.compile(r'<p class="">(.*?)</p>',re.S);
BD = re.findall(findBD,item)[0];
XPath

解析原理:
1. 实例化一个etree对象,且将待解析的数据加载到该对象中
2. 调用etree对象中的xpath方法进行标签定位和文本数据的提取
实例化的方法
1. etree.parse(‘filename’) #本地HTML加载
2. etree.HTML(pagetext) #爬取的pagetext加载

from lxml import etree
tree = etree.HTML(pagetext)
tree.xpath('//meta'); #返回的是一个list

在这里插入图片描述

xpath的查询中不可以出现’tbody’标签

#将字符串转化为selector对象
selector = parsel.Selecor(a.html)

#1.选取所有<a>标签
data = selector.xpath("/html/body/div/ul/li/a").extract()

#2.跨节点获取所有<a>标签
data = selector.xpath("//a").extract()

#3.选取当前节点 对选取标签的下一级多次选取
data1 = selector.xpath("//ul") #不用extract 保证data1是个selector对象 还可以继续用xpath方法
data2 = data1.xpath("./li").extract() #会包含所有子节点

#4.选取当前节点的父节点,获取父节点的class属性值
data1 = selector.xpath("//a") 
data2 = data1.xpath("../@class").extract() #会包含所有子节点

#5.获取第三个li标签的 两个方法
data1 = selector.xpath("//li[3]").extract() #标签索引从1开始
data2 = selector.xpath("//li")[2].extract()

#6.通过属性定位标签 获取第三个a标签
data1 = selector.xpath("//a[@href="link3.html"]").extract()

#7.通过属性定位标签 获取第三个a标签包裹的文本内容
data1 = selector.xpath("//a[@href="link3.html"]/text()").extract()

#8.获取第五个<a>标签的href属性值
data1 = selector.xpath("//li[5]/a/@href").extract() #首先定位到该标签然后取他的属性值

# 模糊查询
data = selector.xpath("//li[contains(@class,'it')]").extract();

实例:爬取站长素材的高清图片
内含图片存储路径相关

import requests
import urllib
import json
import re
import lxml
import os
from lxml import etree
dirname = 'piclib'
if not os.path.exists(dirname):
    os.mkdir(dirname)

def pa():
    url = "https://sc.chinaz.com/tupian/"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36"
    }
    response = requests.get(url=url,headers=headers)
    response.encoding = 'utf-8'
    tree = etree.HTML(response.text)
    img_list = tree.xpath('//div[@id="container"]/div')

    for img in img_list:
        title = img.xpath('./div/a/@alt')[0]+'.rar' #xpath返回的是列表,加[0]才是字符串形式
        href = "http:"+img.xpath('./div/a/@href')[0]
        # print(title,href)
        detail_response = requests.get(url=href,headers=headers)
        detail_response.encoding = 'utf-8'
        # print(detail_response.text)
        downtree = etree.HTML(detail_response.text)
        downurl = downtree.xpath('//div[@class="downbody"]/div[3]/a[1]/@href')[0]

        print(downurl)
        imgpath = dirname+'/'+title
        urllib.request.urlretrieve(downurl,imgpath)

pa()

STEP4:保存数据

其他

代理IP

在这里插入图片描述

selenium VS Scrapy

selenium:you can write Python script to control the web brwoser to do some work automatically.

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

driver = webdriver.Firefox()
driver.get("http://www.python.org")
assert "Python" in driver.title
elem = driver.find_element_by_name("q")
elem.send_keys("selenium")
elem.send_keys(Keys.RETURN)
assert "Google" in driver.title
driver.close()

Scrapy: Scrapy is a web crawling framework for developer to write code to create spider, which define how a certain site (or a group of sites) will be scraped. Scrapy is implemented using a non-blocking (aka asynchronous) code for concurrency, which makes the spider performance is very great.
Scrapy has built-in support for extracting data from HTML sources using XPath expression and CSS expression.
Which One Should You Choose?
The two Python web scraping frameworks are created to do different jobs. Selenium is only used to automate web browser interaction, Scrapy is used to download HTML, process data and save it.

Scrapy框架

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

crawspider

生成crawspider:

scrapy genspider -t crawl csdn "csdn.cn"

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

scrapy模拟登陆

requests:方法1. 直接携带cookies请求页面 ,方法2. 找接口发送请求存储cookie
selenium: 找对应的input标签,输入文字点击登陆
scrapy:方法1. 直接携带cookie 方法2.找到发送post请求的URL,带上信息,发送请求

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值