普通爬虫笔记

通用爬虫

爬虫的定义

网络爬虫(又被称为网页蜘蛛,网络机器人)就是模拟客户端发送网络请求,接收请求响应,一种按照一定的规则,自动地抓取互联网信息的程序.
只要是浏览器能做的事情,原则上,爬虫都能够做

爬虫的分类

  • 通用爬虫:通常指搜索引擎的爬虫
  • 聚焦爬虫:针对特定网站的爬虫

http和https

HTTP

  • 超文本传输协议
  • 默认端口号:80

HTTPS

  • HTTP + SSL(安全套接字层)
  • 默认端口号:443
    HTTPS比HTTP更安全,但是性能更低

HTTP常见请求头

image.png

响应状态码(status code)

200:成功
302:临时转移至新的url
307:临时转移至新的url
404:not found
500:服务器内部错误

str类型和bytes类型

bytes:二进制
互联网上数据的都是以二进制的方式传输的
str :unicode的呈现形式

str bytes如何转化

str 使用encode方法转化为 bytes
bytes通过decode转化为str
编码方式解码方式必须一样,否则就会出现乱码
decode(解码)
encode(编码)

普通爬虫流程图

Requests

作用:发送网络请求,返回响应数据

为什么要学习requests?
requests的底层实现就是urllib
requests在python2 和python3中通用,方法完全一样
requests简单易用
Requests能够自动帮助我们解压(gzip压缩的等)网页内容
中文文档 API: http://docs.python-requests.org/zh_CN/latest/index.html

get请求

#导入requests包
import requests
#请求的网址
url = "https://www.baidu.com"
#url后面的参数?xxx
kw = {'wd':"我爱你"}
#请求头
headers = {"User-Agent":"xxx"}
#GET请求(url,请求头,url后面参数?xxx)
response = requests.get(url,headers=heasers,params=kw)
#打印网页源代码
print(response.content.decode())

post请求

#导入requests包
import requests
#请求的网址
url = "https://www.baidu.com"
#post参数
formdata = {"xxx":"xxx"}
#请求头
headers = {"User-Agent":"xxx"}
#POST请求(url,请求头,post请求参数)
response = requests.post(url,headers=headers,data=formdata)
#json格式
response = requests.post(url,headers=heasers,data=dumps(formdata))
#打印网页源代码
print(response.content.decode())

请求参数

url = "xxx"   #请求网址
headers = {}  #请求头
data = {}     #post请求参数
params={"xx":"我爱你"}#url后面的参数?xxx
#代理
proxies={
      "http":"http://12.34.56.79:9527",
      "https":"https://12.34.56.79:9527"
      }

响应参数

content  #响应内容,返回字节流数据,用decode()解码
text  #响应内容,返回Unicode格式的数据
url  #查看url地址
encoding  #查看响应头字符编码
status_code  #查看状态码
request.headers #查看发过去的报头信息
json()  #如果是json文件可以直接显示
.decode(‘gb18030’,’ignore’) #忽略非法字符

timeout请求超时

https://www.jianshu.com/p/5cf16cb5a362

爬虫处理Cookie和Session

  • 带上cookie、session的好处:

    • 能够请求到登录之后的页面
  • 带上cookie、session的弊端:

    • 一套cookie和session往往和一个用户对应
    • 请求太快,请求次数太多,容易被服务器识别为爬虫

不需要cookie的时候尽量不去使用cookie
但是为了获取登录之后的页面,我们必须发送带有cookies的请求

requests 提供了一个叫做session类,来实现客户端和服务端的会话保持
使用方法:

  • 实例化一个session对象
  • 让session发送get或者post请求
session = requests.session()
response = session.get(url,headers)

模拟登陆的三种方式

  • session
    • 实例化session(session具有的方法和requests一样)
    • session发送请求post请求,对方服务器设置的cookie会保存在session
    • session请求登录后能够访问的页面
  • cookie放在headers中
    • headers = {"Cookie":"cookie字符串"}
  • cookie转化为字典放在请求方法中
    • requests.get(url,cookies={"name的值":"values的值"})

正则使用

import re
re.findall(r"a(.*?)b",body)

\t 制表符 \r 回车 \n 换行

#替换
.replace('\t','').replace('\r','').replace('\n','')

xpath使用

#获取文本
a/text()    #获取a下的文本
a//text()    #获取a下的所有标签的文本
//a[text()='下一页']    #选择文本为下一页三个字的a标签

#@符号
a/@href    #获取url
//ul[@id="detail-list"]    #获取标签属性
//div[contains(@class,"i")]    #div标签包含i属性的
#在xpath最前面表示从当前html中任意位置开始选择
#li//a表示的是li下任何一个标签

//ul/li[1]    #ul下第一个li标签
//ul/li[last()]    #ul下最后一个li标签
//ul/li[last()-1]    #ul下倒数第二个li标签
//ul/li[position()<3]    #ul下前两个li标签

//div/*    #div下所有的标签
//div[@*]    #选取所有带属性的div标签

/li[not(@class="height_5")]  #不包括某个属性节点
//tbody/tr[not(@class or @id)]  #不包括多个属性节点

lxml库

安装lxml:pip install lxml

#导入lxml的etree库
from lxml import etree
response = requests.get(url,headers=headers)
html = response.content.decode()
#利用etree.HTML,将字符串转化为Element对象,Element具有xpath的方法
body = etree.HTML(html)
#在利用xpath取数据,先分组,在遍历取值
data = body.xpath('//div[@id="content-left"]/div')
for i in data:
    #拿到图片连接,列表形式[www.xxxx.com]
    touxiang = i.xpath('.//a/img/@src')
            #拼接"http",并判断头像列表长度是不是大于0,如果不大于0就为空列表,输出None
            touxiang = "http:"+touxiang[0].replace('?imageView2/1/w/90/h/90','') if len(touxiang)>0 else None

lxml使用注意点

  • lxml能够修正HTML代码,但是可能会改错了
  • 使用etree.tostring观察修改之后的html的样子,根据修改之后的html字符串写xpath
  • lxml 能够接受bytes和str的字符串
  • 提取页面数据的思路
    • 先分组,渠道一个包含分组标签的列表
    • 遍历,取其中每一组进行数据的提取,不会造成数据的对应错乱

数据提取之JSON

json.dumps和json.loads()使用方法
数据类型转换
dumps:字典转字符串
loads:字符串转字典

json.dump和json.load()使用方法
json.dump()和json.load()使用方法
用来对json文件的读和写

import requests
import json
#漂亮显示json
from pprint import pprint
#请求json地址
url = "https://www.baidu.com/rec?platform=wise&ms=1&lsAble=1&rset=rcmd&word=python&qid=9063735324500671597&rq=python&from=844b&baiduid=243F13D57A4DA7E648A71F9C61F2160A%3AFG%3D1&tn=&clientWidth=360&t=1541323156347&r=2799"
#请求头信息,如果不显示内容,把所有请求头加进来
headers = {"User-Agent":"xxx"}
#发起请求
response = requests.get(url,headers=headers)
html_str = response.content.decode()
#把字符转成字典,不然不显示中文
ret1 =json.loads(html_str)
#取数据
print(ret1["trans"][0]['dst'])
#漂亮的显示内容
print(pprint(ret1))

json文件读和写

#保存json文件,以utf-8的格式写进去
with open("a.json","w",encoding="utf-8") as f:
    #json.dumps能够把python类型转化为json字符串
    #ensure_ascii=False 显示中文,不然是ascii格式
    #indent=4   换行显示,下一级比上一级多4个空格,跟漂亮显示一样
    f.write(json.dumps(ret1,ensure_ascii=False,indent=4))

#使用json.load提取json文件的数据
with open("a.json",encoding="utf-8")as f:
    ret4 = json.load(f)
    print(ret4)   #字典类型

爬取数据存到mysql数据库

#导入连接数据库的包
from pymysql import connect
#连接数据库
conn = connect(host='localhost',port=3306,db='biaoqing',user='root',passwd='root',charset='utf8')
#获取游标,实现数据库的(增删改查)
cc = self.conn.cursor()
#需要存的数据
aa = (touxing,mingzi,neirong,url)
#存数据库的命令
sql = 'insert into qsbk1(touxiang,mingzi,neirong,url) values ("%s","%s","%s","%s")'
#向数据库添加数据
cc.execute(sql%aa)
#提交数据
conn.commit()
#关闭游标
cc.close()

数据去重

def shuju(self):
rs = self.quchong(url)
#如果数据库有数据,不执行下面的语句
if rs == True:
  continue
#数据去重
def quchong(self,url):
        #数据查询语句
        sql = "select count(1) from qsbk1 WHERE url='%s';" % url
        #在数据库查询
        self.cc.execute(sql)
        #查询一条
        f = self.cc.fetchone()[0]
        #如果查询的数据大于0
        if f > 0:
            #有数据
            return True
        else:
            #没有数据
            return False
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

  • Python开发简单爬虫(Python2.X版本,Eclipse工具) 一、爬虫介绍 爬虫调度端:启动、停止爬虫,...
    凛0_0阅读 2,129评论 2 10
  • 基础知识 HTTP协议 我们浏览网页的浏览器和手机应用客户端与服务器通信几乎都是基于HTTP协议,而爬虫可以看作是...
    腩啵兔子阅读 1,462评论 0 17
  • 网络 理论模型,分为七层物理层数据链路层传输层会话层表示层应用层 实际应用,分为四层链路层网络层传输层应用层 IP...
    FlyingLittlePG阅读 751评论 0 0
  • 1 前言 作为一名合格的数据分析师,其完整的技术知识体系必须贯穿数据获取、数据存储、数据提取、数据分析、数据挖掘、...
    whenif阅读 18,051评论 45 523
  • 目录 学渣讲爬虫之Python爬虫从入门到出门第一讲 目录 爬虫的常用形式 爬虫的基本原理 前期准备 简单爬虫 爬...
    Python编程社区阅读 1,165评论 0 6