Python 爬虫基础学习(four)
- 已经导入,显示导入错误 :新建的py文件名,不能和导入的模块文件名重名
- 视频和图片的下载最重要的式是找到视频或图片的路径
- urllib.request.urlretrive( url=url, filename = filename )
1.BeautifulSoup
1.基本简介
- 获取标签中嵌套标签的内容
1.BeautifulSoup简称:
bs4
2.什么是BeatifulSoup?
BeautifulSoup,和lxml一样,是一个html的解析器,主要功能也是解析和提取数据
3.优缺点?
缺点:效率没有lxml的效率高
优点:接口设计人性化,使用方便
2.安装以及创建
1.安装
pip install bs4
2.导入
from bs4 import BeautifulSoup
3.创建对象
服务器响应的文件生成对象
soup = BeautifulSoup(response.read().decode(), 'lxml')
本地文件生成对象
soup = BeautifulSoup(open('1.html'), 'lxml')
注意:默认打开文件的编码格式gbk所以需要指定打开编码格式
3.节点定位
1.根据标签名查找节点
soup.a 【注】只能找到第一个a
soup.a.name
soup.a.attrs
2.函数
(1).find(返回一个对象)
find('a'):只找到第一个a标签
find('a', title='名字')
find('a', class_='名字')
(2).find_all(返回一个列表)
find_all('a') 查找到所有的a
find_all(['a', 'span']) 返回所有的a和span
find_all('a', limit=2) 只找前两个a
(3).select(根据选择器得到节点对象)【推荐】
1.element
eg:p
2..class
eg:.firstname
3.#id
eg:#firstname
4.属性选择器
[attribute]
eg:li = soup.select('li[class]')
[attribute=value]
eg:li = soup.select('li[class="hengheng1"]')
5.层级选择器
element element
div p
element>element
div>p
element,element
div,p
eg:soup = soup.select('a,span')
3.获取子孙节点
contents:返回的是一个列表
eg:print(soup.body.contents)
descendants:返回的是一个生成器
eg:for a in soup.body.descendants:
print(a)
4.节点信息
(1).获取节点内容:适用于标签中嵌套标签的结构
obj.string
obj.get_text()【推荐】
(2).节点的属性
tag.name 获取标签名
eg:tag = find('li)
print(tag.name)
tag.attrs将属性值作为一个字典返回
(3).获取节点属性
obj.attrs.get('title')【常用】
obj.get('title')
obj['title']
5.节点类型(理解)
节点类型
bs4.BeautifulSoup 根节点类型
bs4.element.NavigableString 连接类型 可执行的字符串
bs4.element.Tag 节点类型
bs4.element.Comment 注释类型
eg:
if type(aobj.string) == bs4.element.Comment:
print('这个是注释内容')
else:
print('这不是注释')
应用实例: 1.股票信息提取(http://quote.stockstar.com/)
import urllib.request
from bs4 import BeautifulSoup
url = 'http://quote.stockstar.com/stock/ranklist_a_3_1_1.html'
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
}
request = urllib.request.Request(url=url,headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('gbk')
soup = BeautifulSoup(content,'lxml')
tr_list = soup.select('#datalist > tr')
for tr in tr_list:
code = tr.find_all('td')[0].get_text()
# '//tbody[@id='datalist']/tr/td[1]/a/text()'
name = tr.find_all('td')[1].get_text()
# '//tbody[@id='datalist']/tr/td[2]/a/text()'
price = tr.find_all('td')[2].get_text()
# '//tbody[@id='datalist']/tr/td[3]/span/text()'
stok = {}
stok['code'] = code
stok['name'] = name
stok['price'] = price
filename = './练习'
with open(filename+'quanshu.json','a',encoding='gb2312') as fp:
fp.write(str(stok))
2.中华英才网-旧版
- referer : 引用页,参照页
Referer的作用?
(1) .页面统计
什么是盗链呢?假设一个网站的首页中想显示一些图片信息,而在该网站的服务器中并没有这些图片资源,它通过在HTML文件中使用img标记链接到其他网站的图片资源,将其展示给浏览者,这就是盗链。盗链的网站提高了自己的访问量,却加重了被链接网站服务器的负担,损害了其合法利益。所以,一个网站为了保护自己的资源,可以通过Referer头检测出从哪里链接到当前的网页或资源,一旦检测到不是通过本站的链接进行的访问,可以进行阻止访问或者跳转到指定的页面。
(2) .防盗链。
刚刚前面有提到一个小 Demo 。我在www.google.com里有一个www.baidu.com链接,那么点击这个www.baidu.com,它的header信息里就有:
referer = 'https://www.google.com'
那么可以利用这个来防止盗链了,比如我只允许我自己的网站访问我自己的图片服务器,那我的域名是www.google.com,那么图片服务器每次取到Referer来判断一下是不是我自己的域名www.google.com,如果是就继续访问,不是就拦截。
将这个http请求发给服务器后,如果服务器要求必须是某个地址或者某几个地址才能访问,而你发送的referer不符合他的要求,就会拦截或者跳转到他要求的地址,然后再通过这个地址进行访问。
(3)防止恶意请求。
比如静态请求是*.html结尾的,动态请求是*.shtml,那么由此可以这么用,所有的*.shtml请求,必须 Referer 为我自己的网站。
(4)空Referer是怎么回事?
直接在浏览器的地址栏中输入一个资源的URL地址,
根据Referer的定义,它的作用是指示一个请求是从哪里链接过来,那么当一个请求并不是由链接触发产生的,那么自然也就不需要**指定这个请求的链接来源**。比如,直接在浏览器的地址栏中输入一个资源的URL地址,那么这种请求是不会包含 Referer 字段的,因为这是一个“凭空产生”的 HTTP 请求,并不是从一个地方链接过去的。
那么在防盗链设置中,允许空Referer和不允许空Referer有什么区别?允许 Referer 为空,意味着你允许比如浏览器直接访问,就是空。
--------------------------------------------------
盗链非本网站访问本网站资源,img标签标记链接到其它网站
referer : 指定链接请求的来源;作用:防止盗链
旧版
# 使用bs4解析方式解析出中华英才网的招聘信息
import urllib.request
def create_request(page):
# http://www.chinahr.com/sou/?orderField=relate&keyword=python&page=2
if page == 1:
url ='http://www.chinahr.com/sou/?keyword=python'
else:
url = 'http://www.chinahr.com/sou/?keyword=python&page=' + str(page)
print(url)
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': '58tj_uuid=039105dd-3965-432e-80eb-a824c948377a; wmda_uuid=3c508db1b18502a85d1db9392bd1bb78; wmda_new_uuid=1; wmda_visited_projects=%3B1732047435009; gr_user_id=7fc504ca-6907-4a84-9eaf-aa9ac461bd4e; als=0; __utma=162484963.1579384879.1562817433.1562817433.1562817433.1; __utmz=162484963.1562817433.1.1.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; yc_yy_tongzhi=true; RecentVisitCity=400_shanghai; RecentVisitCityFullpathPc="36,400"; chrId=b6f21b13e4ae46b8a4aa6891717337aa; gr_session_id_be17cdb1115be298=9a3ea475-a705-42ce-9907-3aacfb95de79; wmda_session_id_1732047435009=1565851666683-ab5967d9-2457-b6d9; channel=social; new_uv=7; utm_source=; spm=; gr_session_id_be17cdb1115be298_9a3ea475-a705-42ce-9907-3aacfb95de79=true; new_session=0; init_refer=https%253A%252F%252Fwww.baidu.com%252Flink%253Furl%253DDRryN24GtBrpwht8ZDFKK-WIZ965UvTl0ZGpHcgt9n2HNslgOMIZ_SdhDy1wV63r%2526wd%253D%2526eqid%253D9fc5b10300022542000000055d550072; xzfzqtoken=89SGChKQ25IzfGQOWKg3DDkc5TWcYopAJxth76ApuUGWIptV966MJyhA4B5JhsFAin35brBb%2F%2FeSODvMgkQULA%3D%3D; gtid=cc31504c027e4ca58b2f193b159d10a2',
# 'Host': 'www.chinahr.com',
'Referer': 'http://www.chinahr.com/sou/?keyword=python',
# 'Upgrade-Insecure-Requests': '1',
# 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',
}
request = urllib.request.Request(url=url,headers=headers)
return request
def get_content(request):
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
return content
from bs4 import BeautifulSoup
def save_content(content):
# print(content)
soup = BeautifulSoup(content,'lxml')
# jobname //div[@class="resultList"]/div/ul/li/span[1]/a
# soup.select('.resultList > div > ul > li > span ')
# salary //div[@class="resultList"]/div/ul/li[2]/span[2]/text()
# cname //div[@class="resultList"]/div/ul/li/span[1]/a
ul_list = soup.select('.resultList > div > ul')
for ul in ul_list:
jobname = ul.select('span[class=e1]')[0].get_text()
salary = ul.select('li[class=l2] > span[class=e2]')[0].get_text()
cname = ul.find_all('span')[2].get_text().strip('\n')
job = {}
job['jobname'] = jobname
job['salary']=salary
job['cname']=cname
with open('job.json','a',encoding='utf-8')as fp:
fp.write(str(job))
if __name__ == '__main__':
start_page = int(input('请输入起始页码'))
end_page = int(input('请输入结束页码'))
for page in range(start_page,end_page + 1):
request = create_request(page)
content = get_content(request)
save_content(content)
2.selenium
- 常用于自动化测试
1.什么是selenium?
(1)Selenium是一个用于Web应用程序测试的工具。
(2)Selenium 测试直接运行在浏览器中,就像真正的用户在操作一样。
(3)支持通过各种driver(FirfoxDriver,IternetExplorerDriver,OperaDriver,ChromeDriver)驱动真实浏览器完成测试。
(4)selenium也是支持无界面浏览器操作的。
2.为什么使用selenium?
模拟浏览器功能,自动执行网页中的js代码,实现动态加载
3.如何安装selenium?
(1)操作谷歌浏览器驱动下载地址
http://chromedriver.storage.googleapis.com/index.html
(2)谷歌驱动和谷歌浏览器版本之间的映射表
http://blog.csdn.net/huilan_same/article/details/51896672
(3)查看谷歌浏览器版本
谷歌浏览器右上角-->帮助-->关于
(4)pip install selenium
4.selenium的使用步骤?
(1)导入:from selenium import webdriver
(2)创建谷歌浏览器操作对象:
path = 谷歌浏览器驱动文件路径
browser = webdriver.Chrome(path)
(3)访问网址
url = 要访问的网址
browser.get(url)
4-1:selenium的元素定位?
元素定位:自动化要做的就是模拟鼠标和键盘来操作来操作这些元素,点击、输入等等。操作这些元素前首先要找到它们,WebDriver提供很多定位元素的方法
方法:
1.find_element_by_id
eg:button = browser.find_element_by_id('su')
2.find_elements_by_name
eg:name = browser.find_element_by_name('wd')
3.find_elements_by_xpath
eg:xpath1 = browser.find_elements_by_xpath('//input[@id="su"]')
4.find_elements_by_tag_name
eg:names = browser.find_elements_by_tag_name('input')
5.find_elements_by_css_selector
eg:my_input = browser.find_elements_by_css_selector('#kw')[0]
6.find_elements_by_link_text
eg:browser.find_element_by_link_text("新闻")
4-2:访问元素信息
获取元素属性
.get_attribute('class')
获取元素文本
.text
获取id
.id
获取标签名
.tag_name
4-3:交互
点击:click()
输入:send_keys()
后退操作:browser.back()
前进操作:browser.forword()
模拟JS滚动:
一种:
js = 'document.body.scrollTop=100000'
二种:
js='document.documentElement.scrollTop=100000'
browser.execute_script(js) 执行js代码
获取网页代码:page_source
退出:browser.quit()
案例练习:糗事百科
from selenium import webdriver
# 指定驱动器的位置
# 定制浏览器+驱动
# 设定浏览的路径
import time
path = 'chromedriver.exe'
browser = webdriver.Chrome(path)
url = 'http://www.baidu.com'
browser.get(url=url)
time.sleep(3)
# 获取输入框,并输入要查询的内容
input = browser.find_element_by_id('kw')
input.send_keys('NBA')
time.sleep(3)
# 点击确定
button = browser.find_element_by_id('su')
button.click()
time.sleep(3)
# 后退
browser.back()
time.sleep(3)
#前进
browser.forward()
time.sleep(3)
# 关闭
browser.quit()
3.Phantomjs
1.什么是Phantomjs?
(1)是一个无界面的浏览器
(2)支持页面元素查找,js的执行等
(3)由于不进行css和gui渲染,运行效率要比真实的浏览器要快很多
2.如何使用Phantomjs?
(1)获取PhantomJS.exe文件路径path
(2)browser = webdriver.PhantomJS(path)
(3)browser.get(url)
扩展:保存屏幕快照:browser.save_screenshot('baidu.png')
4.Chrome handless
1.系统要求:
Chrome
Unix\Linux 系统需要 chrome >= 59
Windows 系统需要 chrome >= 60
Python3.6
Selenium==3.4.*
ChromeDriver==2.31
2.配置:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
path = r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
chrome_options.binary_location = path
browser = webdriver.Chrome(chrome_options=chrome_options)
browser.get('http://www.baidu.com/')
3.配置封装:
from selenium import webdriver
#这个是浏览器自带的 不需要我们再做额外的操作
from selenium.webdriver.chrome.options import Options
def share_browser():
#初始化
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
#浏览器的安装路径 打开文件位置
#这个路径是你谷歌浏览器的路径
path = r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
chrome_options.binary_location = path
browser = webdriver.Chrome(chrome_options=chrome_options)
return browser
封装调用:
from handless import share_browser
browser = share_browser()
browser.get('http://www.baidu.com/')
browser.save_screenshot('handless1.png')
1.文档:
官方文档
http://cn.python-requests.org/zh_CN/latest/
快速上手
http://cn.python-requests.org/zh_CN/latest/user/quickstart.html
2.安装
pip install requests
```python
3.get请求
requests.get()
eg:
import requests
url = 'http://www.baidu.com/s?'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
}
data = {
'wd':'北京'
}
response = requests.get(url,params=data,headers=headers)
定制参数
参数使用params传递
参数无需urlencode
#一个类型(requests.models.Response),六个方法
response.text : 获取网站源码
response.encoding 指定访问或定制编码方式
response.url 获取请求的url
response.content 响应的字节类型
response.status_code 响应的状态码
response.headers 响应的头信息
4:post请求
requests.post()
百度翻译:
eg:
import requests
post_url = 'http://fanyi.baidu.com/sug'
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
}
data = {
'kw': 'eye'
}
r = requests.post(url = post_url,headers=headers,data=data
5:get和post区别?
1:get请求的参数名字是params post请求的参数的名字是data
2 请求资源路径后面可以不加?
3 不需要手动编解码 4 不需要做请求对象的定制
6:proxy定制
在请求中设置proxies参数
参数类型是一个字典类型
eg:
import requests
url = 'http://www.baidu.com/s?'
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
}
data = {
'wd':'ip'
}
proxy = {
'http':'219.149.59.250:9797'
}
r = requests.get(url=url,params=data,headers=headers,proxies=proxy)
with open('proxy.html','w',encoding='utf-8') as fp:
fp.write(r.text)