多线程爬虫

  • 思路
1、将待爬取的URL地址存放到队列中
2、多个线程从队列中获取地址,进行数据抓取
3、注意获取地址过程中程序阻塞问题while True:if not q.empty():url = q.get()... ... else:break
  • 将抓取数据保存到同一文件
# 注意多线程写入的线程锁问题
from threading import Lock
lock = Lock()
lock.acquire()
python代码块
lock.release()
  • 代码实现思路
# 1、在 __init__(self) 中创建文件对象,多线程操作此对象进行文件写入self.f = open('xiaomi.csv','a',newline='')self.writer = csv.writer(self.f)self.lock = Lock()
# 2、每个线程抓取1页数据后将数据进行文件写入,写入文件时需要加锁def parse_html(self):app_list = []for xxx in xxx:app_list.append([name,link,typ])self.lock.acquire()self.wirter.writerows(app_list)self.lock.release()
# 3、所有数据抓取完成关闭文件def main(self):self.f.close()

解析模块汇总

re、lxml+xpath、json

# re
import re
pattern = re.compile(r'',re.S)
r_list = pattern.findall(html)# lxml+xpath
from lxml import etree
parse_html = etree.HTML(html)
r_list = parse_html.xpath('')# json
# 响应内容由json转为python
html = json.loads(res.text)
# 所抓数据保存到json文件
with open('xxx.json','a') as f:json.dump(item_list,f,ensure_ascii=False)# 或
f = open('xxx.json','a')
json.dump(item_list,f,ensure_ascii=False)
f.close()

cookie模拟登录

适用网站及场景

抓取需要登录才能访问的页面

cookie和session机制

# http协议为无连接协议
cookie: 存放在客户端浏览器
session: 存放在Web服务器

人人网登录案例

  • 方法一 - 登录网站手动抓取Cookie
1、先登录成功1次,获取到携带登录信息的Cookie登录成功 - 个人主页 - F12抓包 - 刷新个人主页 - 找到主页的包(profile)
2、携带着cookie发请求** Cookie** User-Agent
import requests
from lxml import etreeclass RenRen():def __init__(self):self.url = 'http://www.renren.com/972492372/profile'self.headers ={"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3","Accept-Encoding": "gzip, deflate","Accept-Language": "zh-CN,zh;q=0.9","Connection": "keep-alive","Cookie": "anonymid=k1t3t0j3-h9gzvq; depovince=HEN; _r01_=1; jebe_key=c8c39106-631c-4bf9-beee-6dd56c4dccb4%7Cda3512308c1175d981f7c3b2f61ac168%7C1571222161507%7C1%7C1571222164814; jebe_key=c8c39106-631c-4bf9-beee-6dd56c4dccb4%7Cda3512308c1175d981f7c3b2f61ac168%7C1571222161507%7C1%7C1571222164824; JSESSIONID=abc-_0r4SWAI-56l3yx3w; ick_login=6e19e2f8-1838-4b76-b4ef-65cc2c216fb4; XNESSESSIONID=abcJ3n1gB0wa0_NeNzx3w; ick=aed15c33-4ef5-43cd-b6bb-89e81fd12e10; __utma=151146938.462399663.1571276995.1571276995.1571276995.1; __utmc=151146938; __utmz=151146938.1571276995.1.1.utmcsr=wan.renren.com|utmccn=(referral)|utmcmd=referral|utmcct=/; __utmt=1; __utmb=151146938.1.10.1571276995; t=134513375b8319bcbed2590712bbaf6e2; societyguester=134513375b8319bcbed2590712bbaf6e2; id=972492372; xnsid=2892efbd; jebecookies=fc6e8057-d6a0-408d-b20a-6dec64b6c264|||||; ver=7.0; loginfrom=null; wp_fold=0","Host": "www.renren.com","Referer": "http://www.renren.com/972492372/newsfeed/photo","Upgrade-Insecure-Requests": "1","User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36",}def parse_html(self):html = requests.get(url=self.url,headers=self.headers).textp = etree.HTML(html)xpath_bd = '//li[@class="birthday"]/span/text()'r_list = p.xpath(xpath_bd)print(r_list)if __name__ == '__main__':spider = RenRen()spider.parse_html()
  • 方法二

原理

1、把抓取到的cookie处理为字典
2、使用requests.get()中的参数:cookies

处理cookie为字典

# 处理cookies为字典
cookies_dict = {}
cookies = 'xxxx'
for kv in cookies.split('; ')cookies_dict[kv.split('=')[0]] = kv.split('=')[1]

代码实现

import requests
from lxml import etreeclass Renren():def __init__(self):self.url = 'http://www.renren.com/972492372/profile'self.headers = {'User-Agent':''}def parse_html(self):html = requests.get(url=self.url,headers=self.headers,cookies=self.get_cookies()).textp = etree.HTML(html)xpatn_db = '//li[@class="birthday"]/span/text()'r_list = p.xpath(xpatn_db)print(r_list)def get_cookies(self):cooks = 'anonymid=k1t3t0j3-h9gzvq; depovince=HEN; _r01_=1; jebe_key=c8c39106-631c-4bf9-beee-6dd56c4dccb4%7Cda3512308c1175d981f7c3b2f61ac168%7C1571222161507%7C1%7C1571222164814; jebe_key=c8c39106-631c-4bf9-beee-6dd56c4dccb4%7Cda3512308c1175d981f7c3b2f61ac168%7C1571222161507%7C1%7C1571222164824; JSESSIONID=abc-_0r4SWAI-56l3yx3w; ick_login=6e19e2f8-1838-4b76-b4ef-65cc2c216fb4; XNESSESSIONID=abcJ3n1gB0wa0_NeNzx3w; ick=aed15c33-4ef5-43cd-b6bb-89e81fd12e10; __utma=151146938.462399663.1571276995.1571276995.1571276995.1; __utmc=151146938; __utmz=151146938.1571276995.1.1.utmcsr=wan.renren.com|utmccn=(referral)|utmcmd=referral|utmcct=/; __utmb=151146938.1.10.1571276995; t=134513375b8319bcbed2590712bbaf6e2; societyguester=134513375b8319bcbed2590712bbaf6e2; id=972492372; xnsid=2892efbd; jebecookies=fc6e8057-d6a0-408d-b20a-6dec64b6c264|||||; ver=7.0; loginfrom=null; wp_fold=0'cookd = {}cooks.split(';')for cook in cooks.split(';'):#非cook:'td_cookie=k1t3'cookd[cook.split('=')[0]] = cook.split('=')[1]return cookdif __name__ == '__main__':spider = Renren()spider.parse_html()
  • 方法三 - requests模块处理Cookie

原理思路及实现

# 1. 思路
requests模块提供了session类,来实现客户端和服务端的会话保持# 2. 原理
1、实例化session对象session = requests.session()
2、让session对象发送get或者post请求res = session.post(url=url,data=data,headers=headers)res = session.get(url=url,headers=headers)# 3. 思路梳理
浏览器原理: 访问需要登录的页面会带着之前登录过的cookie
程序原理: 同样带着之前登录的cookie去访问 - 由session对象完成
1、实例化session对象
2、登录网站: session对象发送请求,登录对应网站,把cookie保存在session对象中
3、访问页面: session对象请求需要登录才能访问的页面,session能够自动携带之前的这个cookie,进行请求

具体步骤

1、寻找Form表单提交地址 - 寻找登录时POST的地址查看网页源码,查看form表单,找action对应的地址: http://www.renren.com/PLogin.do2、发送用户名和密码信息到POST的地址* 用户名和密码信息以什么方式发送? -- 字典键 :<input>标签中name的值(email,password)值 :真实的用户名和密码post_data = {'email':'','password':''}session = requests.session()
session.post(url=url,data=data)#代码
1,先post到站点

程序实现

import requestsclass RenrenLogin():def __init__(self):self.post_url = 'http://www.renren.com/PLogin.do'self.get_url = 'http://www.renren.com/972492372/profile'self.headers = ''# 实例化session对象self.session = requests.session()def pares_html(self):#填写自己的账户密码data = {'email': '18633615542', 'password': '123456'}# 1.先postself.session.post(url=self.post_url, data=data)# 2.在gethtml = self.session.get(url=self.get_url).textprint(html)if __name__ == '__main__':spider = RenrenLogin()spider.pares_html()

selenium+phantomjs/Chrome/Firefox

selenium

  • 定义
1、Web自动化测试工具,可运行在浏览器,根据指令操作浏览器
2、只是工具,必须与第三方浏览器结合使用
  • 安装
Linux: sudo pip3 install selenium
Windows: python -m pip install selenium

phantomjs浏览器

  • 定义
无界面浏览器(又称无头浏览器),在内存中进行页面加载,高效
  • 安装(phantomjs、chromedriver、geckodriver)

Windows

1、下载对应版本的phantomjs、chromedriver、geckodriver
2、把chromedriver.exe拷贝到python安装目录的Scripts目录下(添加到系统环境变量)# 查看python安装路径: where python
3、验证cmd命令行: chromedriver# 下载地址
1、chromedriver : 下载对应版本
http://chromedriver.storage.googleapis.com/index.html
2、geckodriver
https://github.com/mozilla/geckodriver/releases
3、phantomjs
https://phantomjs.org/download.html

Linux

1、下载后解压tar -zxvf geckodriver.tar.gz
2、拷贝解压后文件到 /usr/bin/ (添加环境变量)sudo cp geckodriver /usr/bin/
3、更改权限sudo -icd /usr/bin/chmod 777 geckodriver
  • 使用

示例代码一:使用 selenium+浏览器 打开百度

# 导入seleinum的webdriver接口
from selenium import webdriver
import time# 创建浏览器对象
browser = webdriver.PhantomJS()
browser.get('http://www.baidu.com/')time.sleep(5)# 关闭浏览器
browser.quit()

示例代码二:打开百度,搜索赵丽颖,点击搜索,查看

from selenium import webdriver
import time# 1.创建浏览器对象 - 已经打开了浏览器
browser = webdriver.Chrome()
# 2.输入: http://www.baidu.com/
browser.get('http://www.baidu.com/')
# 3.找到搜索框,向这个节点发送文字: 赵丽颖
browser.find_element_by_xpath('//*[@id="kw"]').send_keys('赵丽颖')
# 4.找到 百度一下 按钮,点击一下
browser.find_element_by_xpath('//*[@id="su"]').click()
  • 浏览器对象(browser)方法
# from selenium import webdriver
1、browser = webdriver.Chrome(executable_path='path')
2、browser.get(url)
3、browser.page_source # HTML结构源码
4、browser.page_source.find('字符串')# 从html源码中搜索指定字符串,没有找到返回:-1
5、browser.quit() # 关闭浏览器
  • 定位节点

单元素查找(1个节点对象)(找到第一个符合条件的就返回)

1、browser.find_element_by_id('')
2、browser.find_element_by_name('')
3、browser.find_element_by_class_name('')
4、browser.find_element_by_xpath('')
5、browser.find_element_by_link_text('')
... ...

多元素查找([节点对象列表])

1、browser.find_elements_by_id('')
2、browser.find_elements_by_name('')
3、browser.find_elements_by_class_name('')
4、browser.find_elements_by_xpath('')
... ...
  • 节点对象操作
1、ele.send_keys('') # 搜索框发送内容
2、ele.click()
3、ele.text # 获取文本内容,包含子节点和后代节点的文本内容
4、ele.get_attribute('src') # 获取属性值

京东爬虫案例

  • 目标
1、目标网址 :https://www.jd.com/
2、抓取目标 :商品名称、商品价格、评价数量、商品商家
  • 思路提醒
1、打开京东,到商品搜索页
2、匹配所有商品节点对象列表
3、把节点对象的文本内容取出来,查看规律,是否有更好的处理办法?
4、提取完1页后,判断如果不是最后1页,则点击下一页# 如何判断是否为最后1页???
  • 实现步骤

找节点

1、首页搜索框 : //*[@id="key"]
2、首页搜索按钮   ://*[@id="search"]/div/div[2]/button
3、商品页的 商品信息节点对象列表 ://*[@id="J_goodsList"]/ul/li
4、for循环遍历后名称: .//div[@class="p-name p-name-type-2"]/a/em价格: .//div[@class="p-price"]评论: .//div[@class="p-commit"]/strong商家: .//div[@class="p-shop"]

执行JS脚本,获取动态加载数据

browser.execute_script('window.scrollTo(0,document.body.scrollHeight)'
)

代码实现


seienium-切换页面(句柄)

使用网站

页面中点开链接出现新的页面,但是浏览器对象browser还是之前页面的对象

应对方案

#1.获取当前所有句柄(窗口):列表[<page1>,<page2>]
all_handles = browser.window_handles
#2.切换句柄
browser.switch_to.window(all_handles[1]

Python爬虫(七)相关推荐

  1. Python爬虫(七)_非结构化数据与结构化数据

    页面解析与数据提取 实际上爬虫一共就四个主要步骤: 定(要知道你准备在哪个范围或者网站去搜索) 爬(将所有的网站的内容全部爬下来) 取(分析数据,去掉对我们没用处的数据) 存(按照我们想要的方式存储和 ...

  2. [Python爬虫] 一、爬虫原理之HTTP和HTTPS的请求与响应

    一.HTTP和HTTPS HTTP协议(HyperText Transfer Protocol,超文本传输协议):是一种发布和接收 HTML页面的方法. HTTPS(Hypertext Transfe ...

  3. [Python爬虫] 三、数据抓取之Requests HTTP 库

    往期内容提要: [Python爬虫] 一.爬虫原理之HTTP和HTTPS的请求与响应 [Python爬虫] 二.爬虫原理之定义.分类.流程与编码格式 一.urllib 模块 所谓网页抓取,就是把URL ...

  4. [Python爬虫] 九、机器视觉与机器图像识别之Tesseract

    往期内容提要: [Python爬虫] 一.爬虫原理之HTTP和HTTPS的请求与响应 [Python爬虫] 二.爬虫原理之定义.分类.流程与编码格式 [Python爬虫] 三.数据抓取之Request ...

  5. [Python爬虫] 四、数据抓取之HTTP/HTTPS抓包工具Fiddler

    往期内容提要: [Python爬虫] 一.爬虫原理之HTTP和HTTPS的请求与响应 [Python爬虫] 二.爬虫原理之定义.分类.流程与编码格式 [Python爬虫] 三.数据抓取之Request ...

  6. [Python爬虫] 二、爬虫原理之定义、分类、流程与编码格式

    往期内容提要: [Python爬虫] 一.爬虫原理之HTTP和HTTPS的请求与响应 一.爬虫的定义.分类和流程 爬虫定义 网络爬虫(又被称为网页蜘蛛,网络机器人)就是模拟浏览器发送网络请求,接收请求 ...

  7. [Python爬虫] 六、数据提取之XPath与lxml类库

    往期内容提要: [Python爬虫] 一.爬虫原理之HTTP和HTTPS的请求与响应 [Python爬虫] 二.爬虫原理之定义.分类.流程与编码格式 [Python爬虫] 三.数据抓取之Request ...

  8. 孤荷凌寒自学python第七十九天开始写Python的第一个爬虫9并使用pydocx模块将结果写入word文档...

    孤荷凌寒自学python第七十九天开始写Python的第一个爬虫9 (完整学习过程屏幕记录视频地址在文末) 今天在上一天的基础上继续完成对我的第一个代码程序的书写. 到今天终于完成了对docx模块针对 ...

  9. python(七)爬虫框架

    python(七)爬虫框架 常见的爬虫框架 Scrapy框架:Scrapy框架是一套比较成熟的Python爬虫框架,是使用Python开发快速,高层次的信息爬取框架,可以高效的爬取web页面并提取出结 ...

  10. python爬虫 库_七款必备的Python爬虫库,你知道几个?

    很多你需要的信息数据都是在网站内,虽然有些网站的数据会以整洁.结构化的形式呈现,但大部分网站却无法做到这样.因此,当你想要获得一些数据的时候,你需要一些爬虫工具帮助抓取,然后再对其进行分析.今天,将介 ...

最新文章

  1. TensorFlow官方课程开启,机器学习上车吧
  2. [置顶] 自己动手实现OpenGL-OpenGL原来如此简单(二)
  3. 二、MySql优化七个查询命令特征
  4. 微信小程序引入WeUI
  5. SpringCloud:Hystrix 熔断机制(基本配置、服务降级、HystrixDashboard服务监控、Turbine聚合监控)
  6. delphi查看源码版本_[Mybatis]-IDEA导入Mybatis源码
  7. Oracle锁机制的总结【转】
  8. 天弘基金交易数据清算从8小时缩至1.5小时 解决余额宝算力难题
  9. IPC 进程间通信方式——管道
  10. 【Python数据分析】Python3操作Excel(二) 一些问题的解决与优化
  11. put与putIfAbsent区别
  12. Mac屏幕录制GIF动图
  13. 蓦然回首,灯火阑珊——自考总结
  14. 二烷基二硫代磷酸锌添加剂的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  15. 什么是代码,源文件、编辑和编译?
  16. 幼儿园计算机教师论文,幼儿园计算机辅助教学中教师角色定位研究
  17. 随机梯度下降(Stochastic gradient descent)
  18. 基于Ubuntu20.04 GTX960m搭建cudacunn
  19. [附源码]SSM计算机毕业设计宠物寻回系统JAVA
  20. C语言 将十六进制字符串转为十六进制数 (二进制、十进制都适用)

热门文章

  1. rhel7红帽7制作全自动安装光盘-实战
  2. Matlab中mex的使用方法
  3. 北京车展新风向,百度车联网开启智能汽车新时代
  4. 百度智能云重庆工业互联网平台正式亮相,深耕重庆,辐射西南
  5. 软件开发管理模型及分析比较
  6. 新来一个技术总监:禁止戴耳机写代码,发现就扣绩效。。
  7. 多商户商城系统功能拆解32讲-平台端营销-限时秒杀
  8. 显卡,显卡驱动,GPU,CUDA,cuDNN
  9. 会员电商和传统电商的区别在哪里?
  10. 欧债收益率大幅攀升,欧央行政策放宽力度令人失望