python 之禅:

Beautiful is better than ugly.(美丽优于丑陋)
Explicit is better than implicit.(直白优于含蓄)
Simple is better than complex.(简单优于复杂)
Complex is better than complicated.(复杂优于繁琐)
Readability counts.(可读性很重要)

1.通用性爬虫(搜索引擎)

pagerank:

网页搜索排名–nofollow算法可以抵制一些垃圾投票

以图搜图
听歌识曲
robots协议(道德层面),保存在根目录下:https://www.taobao.com/robots.txt

2.聚焦爬虫

  • HTTP:

    超文本传输协议,默认端口80

    2016年提出HTTP/2.0 版本新增并发请求

  • HTTPS(http + ssl):

    http + ssl(安全套接字层),默认端口443

    相对于http更安全,但是性能较低

页面数据获取途径:

  • 当前url相应中
  • ajax异步请求相应中
  • js生成

相应状态码:

  • 1xx:浏览器发送的请求不完整
  • 2xx:请求正常完成
  • 3xx:
    • 302, 307:重定向
    • 304:资源未发生变更,直接使用本地缓存
  • 4xx:请求的资源地址有误,服务器无法提供相应
    • 404:请求路径不存在
    • 403:拒绝访问(权限)
  • 5xx:服务器相应过程中出现错误
    • 500:服务器内部错误

字符

字符集:多个字符的集合(ASCII, GB2312, GB18030, Unicode)

ASCII 编码是1个字节,Unicode编码是2个字节,UTF-8是Unicode边长的编码方式(可以是1, 2, 3个字节)

r = requests.get(url):

r.encoding(‘utf-8’)

r.text (默认由headers进行推测,获得解码后str类型数据)

常用方法:

    r.content  # 获得bytes类型数据r.status_coder.request.headersr.headers

命令行修改:

    ~/.bashrc添加:alias fanyi='python             /User/linlin/Desktop/fanyi.py'source ~/.bashrc

代理:

为什么使用代理?

  • 让服务器以为不是同一个客户端在请求
  • 防止我们的真实地址被泄露,防止被追究

nginx反向代理

保持登陆状态

1.携带登录后cookie至headers中

2.在请求方法中添加cookies参数(字典)

3.创建session实例

    se = requests.session()se.post()  # 登陆,获得登陆成功cookiese.get()  # 自动携带cookie发送请求

js定位:

  • 选择会出发js事件的按钮,点击event listener
  • search all file(request_url或者其中关键字)

获取响应中的cookie

    response.cookies  # 获取cookie对象requests.utils.dict_from_cookiejar(response.cookies)  # 获得cookie字典requests.cookiejar_from_dict({key:value})  # 将字典转化为cookie对象

url地址编解码:

    requests.utils.unquote()  # 解码requests.utils.quote()  # 编码

SSL证书验证跳过

requests.get(url, verify=False)

请求超时验证

requests.get(url,timeout=10) # 超时时间10秒

第三方包安装

  • pip install package_name
  • python setup.py install
  • pip install *.whl

返回响应中不是标准json字符串

callback = jsonp1参数可以省略

格式化输出

pprint() # pretty print

格式化写入

f.write(json.dumps(str, ensure_ascii = False, indent = 4)

类文件对象

具有read() 或者wrtie() 的对象就是类文件对象

可以使用json.load()json.dump() 转换

正则表达式

  • . 匹配除\n之外的所有
  • \d 数字
  • \D 非数字
  • \s 空白字符(空格),包含\r\t\n\f\v
  • \S 非空白
  • \w 单词[A-Za-z0-9_]
  • \W 非单词字符
  • * 任意次数
  • + 1次或无限次
  • ? 非贪婪
  • {m} m次数

re.VERBOSE(或re.X) 可使正则表达式结构化,形式更易读.

re.DOTALL(或re.S) 使得. 匹配包括换行符在内的任意字符.

re.IGNORECASE(或re.I) 使得匹配对大小写不敏感.

re.MULTILINE(或re.M) 使得多行匹配生效,影响^$ 的首尾匹配

re.compile()提前进行编译,例:r = re.compile('\d');p.findall(str) # 需要添加re.S等参数时,需要提前在编译时添加

Xpath

  • 获取文本 /html/title/text()
  • 获取属性 /html/link/@href
  • 获取列表 /html/a
  • 当前节点 ./
  • 上一级节点 ../
  • 获取列表中第一个 /html/a[1]
  • 取列表中最后一个 /html/a[last()]
  • 取前两个/html/a[position()<3]
  • 或者/html/a[1]|/html/a[3] //a[1]|//[3]
  • 当前节点中某个位置标签 /html//a
  • 选择id或者class固定的标签 /html/a[@id="id"] /html/a[@class="class"]
  • 获取当前标签下所有标签的文本 /html/a//text()
  • 根据文本筛选 //a[text() = '下一页']

lxml

  • 导入lxml的etree库

    • lxml会自动修改html代码
  • html = etree.HTML(text) # text 可以是str或者bytes,获得html对象
  • html.xpath()
  • etree.tostring(html) # 转换为字符串,提前查看修正后代码
  • 包含(class包含i的divpyth: //div[contains(@classs, "i")]

多线程

    import threadingfrom queue import Queueurl_queue = Queue()url_queue.put()  url_queue.get()url_queue.task_done()  # 标志当前取出完成,任务队列-1 t_list = list()t1 = threading.Thread(target=xxx)t_list.append(t1)for i in range(3):  # 创建3个线程实例t2 = threading.Thread(target=aaaa)t_list.append(t2)for i in t_list:t.setDaemon(True)  # 设置主线程为守护线程(该线程不重要,主线程结束,子线程立即结束)i.start() for q in queue_list: # queue_list 为当前所有子线程队列列表q.join()  # 使主线程等待

selenium&phantomJS

安装:
注意事项:

selenium 首页选择会在页面加载完成后执行,后续页面会直接执行,所以,需要的请求后续页面后强制睡眠几秒钟,常用time.sleep(3) ;也可以使用 1.显式等待WebDriverWait(driver, 10), until(EC.presence_of_element_located((By.ID,"myDynamicElement")) 直到myDyamicElement的id出现 2. 隐式等待

    driver.implicitly_wait(10)  # 等待10s,默认0driver.get("http://www.xxxxx.com/loading")myDynamicElement = driver.find_element_by_id("myDynamicElement")
使用
    from selenium import webdriverdriver = webdirver.Chrome()  # 实例化浏览器driver.set_window_size(1920, 1080)  # 设置窗口大小driver.maximizez-window()  # 最大化窗口driver.get(url)  driver.save_screenshot('xxx.png') # 保存浏览器截图driver.find_element_by_id() 返回对象driver.find_elements_by_class() # 返回对象列表driver.find_element_by_id('kw').send_kdy('搜索关键字')drvier.find_element_by_id('su').click()  # 点击选中对象driver.find_element_by_class_name()  # 根据类名来筛选,类名只能写一个!!! driver.page_source # 获取渲染后页面代码driver.get_cookies() # 获取当前页面cookiedriver.find_element_by_di('kw').send_key(Keys.CONTROL, 'a')  # ctrl +a 全选输入框内容driver.find_element_by_id('kw').send_key(Keys.RETURN)  # 模拟点击Enter回车键driver.find_element_by_id('kw').clear()  # 清除输入框内容driver.current_url # 当前请求的urldriver.close() # 关闭当前页面driver.quit() # 退出浏览器

云打码

用来识别验证码

鼠标动作链

    #导入 ActionChains 类
from selenium.webdriver import ActionChains# 鼠标移动到 ac 位置
ac = driver.find_element_by_xpath('element')
ActionChains(driver).move_to_element(ac).perform()# 在 ac 位置单击
ac = driver.find_element_by_xpath("elementA")
ActionChains(driver).move_to_element(ac).click(ac).perform()# 在 ac 位置双击
ac = driver.find_element_by_xpath("elementB")
ActionChains(driver).move_to_element(ac).double_click(ac).perform()# 在 ac 位置右击
ac = driver.find_element_by_xpath("elementC")
ActionChains(driver).move_to_element(ac).context_click(ac).perform()# 在 ac 位置左键单击hold住
ac = driver.find_element_by_xpath('elementF')
ActionChains(driver).move_to_element(ac).click_and_hold(ac).perform()# 将 ac1 拖拽到 ac2 位置
ac1 = driver.find_element_by_xpath('elementD')
ac2 = driver.find_element_by_xpath('elementE')
ActionChains(driver).drag_and_drop(ac1, ac2).perform()

填充下拉框

# 导入 Select 类
from selenium.webdriver.support.ui import Select# 找到 name 的选项卡
select = Select(driver.find_element_by_name('status'))#
select.select_by_index(1)  # index 索引从 0 开始
select.select_by_value("0")  # value是option标签的一个属性值,并不是显示在下拉框中的值
select.select_by_visible_text(u"未审核")  # visible_text是在option标签文本的值,是显示在下拉框的值# 全部取消
select.deselect_all()

弹窗处理

alert = driver.switch_to_alert()

页面切换

# 第一种
driver.switch_to.window("this is window name")# 第二种
for handle in driver.window_handles:driver.switch_to_window(handle)

页面前进和后退

driver.forward()     #前进
driver.back()        # 后退

mongodb

备份: (终端下)

mongodump -h dbhost -d db_name -o save_route

恢复:

mongorestore -h dbhost -d db_name –dir dir_route

聚合:

  • db.collection.aggregate({管道:{表达式}})

    • $match
    • $group
    • $project
    • $sort
    • $limit
    • $skip
    • $unwind
  • db.orders.aggregate([{$match:{status:'A'}},{$group:{_id:"$cust_id", total:{$sum:1}}}])
    • $match 获得的值交给$group继续处理;$sum:1表示以1为倍数求和

索引:

​ db.集合.ensureIndex({属性:1},{‘unique’:true}) —设置唯一,可以去重(配合布隆过滤器)

​ db.集合.getIndexes() —查询索引

​ db.集合.dropIndex({})

查询时间:

​ db.stu.find({name:‘“test10000”’}).explain(‘executionStats’)

MySQL & MongoDB:

  • 创建数据库

    • create database 数据库名 character set UTF8
    • use 数据库名
  • 查看数据库

    • show databases;
    • show dbs show databases
  • 删除数据库

    • drop database数据库名
    • db.dropDatabase() –在使用当前db状态下
  • 创建表或者集合

    • create table 表明 (字段名 类型 约束)

      • create table user(name varchar(20) unique, id integer primary key auto _increment, img varchar(20));
    • db.集合名.insert({})
      • db.createCollection(集合名, {参数})
  • 删除表

    • drop table 表名
    • db.集合名.drop()
  • MySQL修改表

    • alter table 表名 add/modify/drop/change 字段名 数据类型 约束

      • alter table user add age integer;
      • alter table user name varchar(50);
      • alter table user drop img;
      • alter table user change name username varchar(70);
    • rename table旧表名 to 新表名; – 重命名表名
  • 数据增删改

    • 插入

      • insert into 表名(字段名) values (值)

        • inser into 表名 values(所有字段内容)
      • db.集合名.insert({})
        • db.集合名.save({}) 存在则更新,不存在则新增
    • 修改
      • update 表名 set 字段名=值, 字段名=值 where 条件
      • db.集合名.update({条件}, {改值}, {multi:true/false})
        • db.集合名.update({条件},{$set:{修改}}) 更改当前字段
    • 删除
      • delete from 表名 where 条件

        • truncate table 表名 —-回滚id
      • db.集合名.remove({条件],{justOne:true/false})
    • 查询
      • select * from 表名 where 条件
      • db.集合名.find({条件})
      • db.集合名.find({条件}).pretty()
      • 条件
        • 比较

          • age > 18
          • {$gt:{age:18}}
        • 逻辑
          • where age > 18 and age < 30
          • {age:{$gte:18}, age:{$lt:30}}
          • where age >20 or age < 18
          • {$or:[{age:{$gt:20}, {age:{$lt:18}}}]}
          • where not age > 18
          • {$not:{age:{$gt:18}}}
        • 范围
          • where age in [18, 18, 20]
          • where age between 18 and 20
          • {age:{$in:[18, 20]}}
        • 正则/模糊
          • where name like “张%”
          • where name like “张_”
          • {name:/^张/}
          • {name:{$regex:"^张"}}
        • 自定义查询
          • {$where:function(){return this.name=="张三"}}
        • 分页
          • select * from 表名 where 条件 limit x,y ;—x从那条开始,y查询几条
          • db.集合名,find({条件}}).skip(x).limit(y)
        • 去重
          • select distinct 字段名 from 表名 where 条件;
          • db.集合名.distinct(“去重字段”, {条件})
        • 投影
          • select 字段名, 字段名 from 表名 where 条件;
          • db.集合名.find({条件}, {_id: 0, 字段,:1}) — 0不显示, 1 显示
        • 排序
          • select * from 表名 where 条件 order by 字段 desc/asc;
          • db.集合名.find({条件}).sort({字段:-1, 字段:1}) —1升序,-1降序
        • 统计
          • select count(*) from 表名 where 条件
          • db.集合名.count({条件})
          • db.集合名.find({条件}).count()
  • MySQL高级查询[可以省略的参数]

    • SELECT select_expr [,select|_expr,...] [      FROM tb_name[WHERE 条件判断][GROUP BY {col_name | postion} [ASC | DESC], ...] [HAVING WHERE 条件判断][ORDER BY {col_name|expr|postion} [ASC | DESC], ...][ LIMIT {[offset,]rowcount | row_count OFFSET offset}]
      ]
    • 关联查询

      • 交叉(cross join)(选取两个表中所有排列组合)

        • select * from 表A, 表B
        • select * from 表A, [cross] join 表B
      • 内链接(inner join)
        • select * from 表A, 表B where 关联条件(a.id= b.id)
        • select * from 表A [inner] join 表B on 关联条件
      • 外链接(outer join)
        • 左(left [outer] join

          • 在内连接的基础上,把左表中没有关联上的记录不上,右表使用null填充数据
          • select * from 表A left [outer] join 表B on 关联条件
        • 右(right [outer] join
          • select * from 表A right[outer] join 表B on 关联条件
    • 子查询(查询嵌套:一个查询作为另一个查询的基础)

      • 可以放在select/where/from等后边

pymongo

from pymongo import MongoClient
client = MongoClient(host="", port="27017")
collection = client['db_name']['collections_name']
collection.insert({})
collection.insert_many([{},{},{}])
t = collection.find()  # 返回游标对象,可以遍历一次,也可以进行强制类型转换为list()
collection.update_one()
collection.update_many()
collection.delete_one()
collection.delete_many()# 获得id可以被100整除的列
ret = collection.find()
data = list(ret)
data = [i for i in data if i["_id"]%100 == 0]

回调函数,事件驱动

回调函数:创建但不执行的函数

事件驱动:靠事件来驱动程序的执行的编写代码的方式

  • 三要素

    • 事件
    • 事件源
    • 事件处理程序(监听器,监听程序)
  • 三个步骤
    • 事件源
    • 编写事件处理程序
    • 绑定(οnclick=)

scrapy

日志:

import logging  # 使用python自带日志功能
logging.basicConfig(level=logging.WARNING,  filename='./log/log.txt',  filemode='w',  format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
logger = logging.getLogger(__name__)  简单输出当前文件名
logger.warning(e)

scrapy.Request:

yield scrapy.Request(url,[callback, method="GET", headers, body, cookies, meta, dont_filter=False]
)

请求数据重复

请求传递item为同一个,多线程操作item会造成数据覆盖,可以使用deepcopy来修正

crawl spider

scrapy genspider -t crawl spider_name allow_domain

参数:

多个rules提取的url之间不能传递参数

allow:正则,先提取,后不提取(会自动补全url)

callback:处理响应的函数(不能定义parse函数,避免覆盖父类方法)

follow:请求后资源是否继续被筛选

deny:满足正则的url不被请求

process_links:指定该spider中哪个的函数将会被调用,从link_extractor中获取到链接列表时将会调用该函数。该方法主要用来过滤。

process_request:指定该spider中哪个的函数将会被调用, 该规则提取到每个request时都会调用该函数。 (用来过滤request)

downloadmiddleware:

添加代理ip:

reqeust.meta[‘proxy’] = ‘http://127.0.0.1:455’

pycharm发布代码

tools – deployment – sftp

Crontab 定时执行

安装:sudo apt-get install cron

配置:crontab -e

​ 分 小时 日 月 星期 命令

​ 0-59 0-23 1-31 1-12 0-6 command

查看:crontab -l

tail -f 1.log有输出就会展示

星期0表示周日

python-spider个人笔记相关推荐

  1. Python 网络爬虫笔记11 -- Scrapy 实战

    Python 网络爬虫笔记11 – Scrapy 实战 Python 网络爬虫系列笔记是笔者在学习嵩天老师的<Python网络爬虫与信息提取>课程及笔者实践网络爬虫的笔记. 课程链接:Py ...

  2. Python 网络爬虫笔记10 -- Scrapy 使用入门

    Python 网络爬虫笔记10 – Scrapy 使用入门 Python 网络爬虫系列笔记是笔者在学习嵩天老师的<Python网络爬虫与信息提取>课程及笔者实践网络爬虫的笔记. 课程链接: ...

  3. Python 网络爬虫笔记9 -- Scrapy爬虫框架

    Python 网络爬虫笔记9 – Scrapy爬虫框架 Python 网络爬虫系列笔记是笔者在学习嵩天老师的<Python网络爬虫与信息提取>课程及笔者实践网络爬虫的笔记. 课程链接:Py ...

  4. 【Python】开发笔记

    [Python]开发笔记 1. 开发工具篇 1)前言 2)VScode VScode搭建Python环境 简明教程 3)Pycharm 4)Visual Studio 5)Jupyter Lab/Ju ...

  5. Python爬虫学习笔记 -- 爬取糗事百科

    Python爬虫学习笔记 -- 爬取糗事百科 代码存放地址: https://github.com/xyls2011/python/tree/master/qiushibaike 爬取网址:https ...

  6. python爬虫课程笔记

    11 Oct 2020 国庆长假公司上了一个新项目,一直没有休息,10月9号开了爬虫班,事情真是一大堆.开班典礼和第一节课还是挺简单的,代码都没敲.第一节课主要讲了端口的概念,通讯协议,数据拆包,数据 ...

  7. python爬虫学习笔记3.2-urllib和request练习

    python爬虫学习笔记3.2-urllib和request练习 一.urllib练习 1.百度贴吧案例 需求 分析 手动测试查询流程 观察页面 分析特殊部分 https://tieba.baidu. ...

  8. 爬虫(Spider)学习笔记

    title: Spider(蜘蛛)笔记 date: 2018-06-30 11:23:30 tags: Spider基础 作者:李忠林 Github: https://github.com/Leezh ...

  9. python做直方图-python OpenCV学习笔记实现二维直方图

    本文介绍了python OpenCV学习笔记实现二维直方图,分享给大家,具体如下: 官方文档 – https://docs.opencv.org/3.4.0/dd/d0d/tutorial_py_2d ...

  10. Python中知识点笔记

    Python中知识点笔记 Wentao Sun. Nov.14, 2008 来这个公司11个月了,最开始来的一个笔记本用完了,里面都是工作时记录的一些片段,看到一块自己当时学/写 python程序时记 ...

最新文章

  1. Ubuntu安装软件失败
  2. “汇新杯”新兴科技+互联网创新大赛青年创客专项赛决赛
  3. 【opencv】1.opencv安装、编译、运行等踩坑记录
  4. LeetCode - 4. 寻找两个正序数组的中位数
  5. 022-红黑树(三)
  6. Runtime 在IOS中的详细使用
  7. #leetcode刷题之路27-移除元素
  8. SkyDrive和Google Drive比较
  9. vb利用计算机 鸡兔同笼,VB程序题:利用计算机解决古代数学瓿“鸡兔同笼问题”。即已知在同一笼子里有总数为m只鸡和兔,鸡和兔的总脚数为n只,求鸡和兔各有多少只? VB源码 龚沛曾...
  10. python爬网易云音乐评论最多的歌_Python爬取网易云音乐上评论火爆的歌曲
  11. vue + element插件 首次运行白屏原因分析
  12. CentOS 7.6镜像下载
  13. 关于ioncube扩展的安装和使用
  14. 立委科普:问答系统的前生今世
  15. unity中碰撞检测方法
  16. 中止执行后超过2年_超过两年是否可以申请强制执行
  17. 两年后,再议“站内信”的实现
  18. 六、图(上):六度空间
  19. 3DMAX游戏角色头发建模教程
  20. CCTV 2006 感动中国人物揭晓

热门文章

  1. 互联网思维的“独孤九剑”
  2. 初夏小谈:浅谈字节序,TCP,UDP协议
  3. 只知道三角形三条边长不知道高是多少,用Python如何求三角形周长和面积,海伦公式帮你解决这个难题
  4. TMS320F28035 之ECAP捕获频率
  5. GLFWError #65542 Happen, WGL: The driver does not appear to support OpenGL的问题处理经历
  6. C语言 生成随机数 srand用法 伪随机函数rand srand需不需要重新播种问题 srand该不该放在循环里
  7. java版微信三级分销完整源码
  8. HORNER(霍纳)法则的C实现以及算法比较 2.10
  9. 机器人java指南_Zmud新手机器人指南
  10. 群晖搭建discuz论坛