基础学习

用到了requests 和BeautifulSoup库 ,安装使用pip命令在cmd进行安装就行,这里都是先进行了解,之后再做几个小实例进行练习

先解释下爬虫,python爬虫可以通过获取网页的html代码,对其进行分析,得到可见和不可见的数据,也可以像网络发送请求,执行相应的操作,概括来说就这样

流程分为以下几步:

1.通过域名获取html代码数据

2.根据我们所需要的信息来对数据进行解析

3.存储目标信息

这是一个页面的基本流程,抓取多个页面时,对多个页面这样子做就行了,

首先为了对HTML代码进行分析,我们必须要了解下它,html比较简单我感觉,自己看看文档就能看得懂了,这里不说了,

下面先看一个简单的例子,对整个流程有一个认知

使用requests获取html,注意这里获取的是字符串,

 

import requests

url ="http://www.runoob.com/html/html-intro.html"
r = requests.get(url) #对获取的内容用他的编码方式进行编码并解码,解决乱码问题 html = r.text.encode(r.encoding).decode()

 

 获取之后,我们将其字符串转换为BeautifulSoup对象,html.parser是对解析器进行设置(Python标准库),还有html4lib,xml等,但是要安装其他c语言库,这里先用python标准库,具体用途不清楚,这里先用着, 回头去官网看

from bs4 import BeautifulSoup

soup  = BeautifulSoup(html,'html.parser')

 

获取到之后,soup.标签名就可以获取到相应标签的信息,例soup.title

如果想要获取所有的,可以用findAll方法进行,soup.findAll('h2')   找出所有h2标签,我们更关注的是其中的具体内容,可以这样做,遍历并取出其中文本生成content列表

content = [x.text for x in soup.findAll('h2')]

 

下面使用pandas将其存储为Excel表格,,设置列名称为url,存储为csv文件,目录为 当前目录

import pandas as pd
df = pd.DataFrame(content,columns=[url]) 
df.to_csv('爬虫.csv')

 

最后一个基础流程,转到其他网页进行爬取,注意在获取网址时,注意网址时相对地址还是绝对地址,相对地址的话需要在前面添加字符拼接成绝对网址,后面才能访问,并且要根据需要对网址进行筛选,

比如需要获取html下面的网址,就需要判断网址的前面几个字符是否是html才行,如下

 获取所有/html开头的链接,需要先判断是否有链接属性
links = [x for x in soup.findAll('a') if x.has_attr('href') and x.attrs['href'][0:5] == '/html']
urls = set([x.attrs['href'] for x in links])
absoulte_urls = {'http://www.runoob.com' + i for i in urls}
absoulte_urls.discard(url)

 

获取所有链接之后,由于链接是相对路径,所以需要进行拼接得到绝对路径,为了避免重复元素,我们将它存储为一个集合:set()  之后再拼接存储为字典,并去除并去除本身的url,

之后我们可以进行循环爬取,比如下面的,

df = pd.DataFrame()
for i in absoulte_urls:
    r = requests.get(i)
    html = r.text.encode(r.encoding).decode()
    soup = BeautifulSoup(html, 'html.parser')
    content = [x.text for x in soup.findAll('h2')]
    dfi = pd.DataFrame(content, columns=[i])
    df = df.join(dfi, how='outer')

 

遍历获取好的绝对链接,按照原本的步骤进行分析, 找到h2标题,并将其整合存储到df当中去,这里还是比较简单的,下面的记录一下常用的网络爬虫工具

 

下面对requests进行说明,

request可以进行post和get等请求的处理,也可以处理form表单,进行身份验证等,主要用于和服务器进行通信的,具体查看官方文档http://docs.python-requests.org/zh_CN/latest/user/quickstart.html

status_code  返回的状态码

1.查看网页元素

2.查看网络通信

3.查看请求的headers(这个有时候请求失败时就需要进行设置,之前爬取校园网时候就是这样)

4.定位xhr动态请求url(比如有一些信息必须时下拉时才会刷新出新的东西,并不在刚开始的网址,而是要看他的通信记录,抓取相应的包才行,这就是动态请求,所以获取url时,需要先查看响应再查看headers里面是否有想要的 )

BeautifulSoup和re 

正则表达式是按照一定规则进行字符串匹配的,BeautifulSoup本质上就是用re实现的,对html代码进行分析,具体的看收藏的博客文档进行学习吧,根据需要的功能进行学习就行哈,

 

对于一些动态网页来说,需要将鼠标点击或者放置在某个位置才会显示相应的信息,requests无法运行css,js脚本(不改变当前的url),这时就需要来模拟用户的操作,使用selenium进行,它本来是用于进行测试脚本能否在不同的浏览器上面能否执行的,

phantom是一种无头浏览器, 可以进行运行,js脚本,解析css,html文件但是却不需要图形界面,selenium和phantom联合可以进行破解反爬虫,抓包,抓取动态网页等,但是它的速度相应的会慢一点

 

下面记录一下对于复杂html的解析

一般常用的就是find和findAll方法,他们前两个参数是标签和属性,name ,attr,一般也就用这两个 

name = {'g1','h2'}  这是一个集合,满足一个就行了, attrs传入的是一个字典,对查找的属性进行限制比如 attrs = {'class':{'article','aaaa'}} 即标签当中的class属性必须是这两个当中的一个

、。。。。。。。好吧,忘记保存了,,,,,懒得写了,就贴一些代码供自己以后参考吧

# 获取风景图片

url ="http://sc.chinaz.com/tupian/fengjingtupian.html"
headers ={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36 LBBROWSER'}
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text.encode(r.encoding).decode(), 'html.parser')
# 得到图片地址
imgs = soup.findAll(lambda tag: tag.name == 'img' and tag.has_attr('src2'))
src2s = [i.attrs['src2'] for i in imgs]
j = 1
# 根据url获取图片并进行存储,wb表示二进制存储,content用于获取图片内容
os.chdir('C:\\learn\\python\\爬虫基础学习')
filedir = os.getcwd() + '\\风景'
if not os.path.exists(filedir):
    os.mkdir(filedir)
for i in src2s:
    ri = requests.get(i, headers=headers)
    if ri.status_code == 200:
        with open(filedir+'\\%s.jpg' % j, mode='wb') as f:
            print('正在下载第%d张图片' % j)
            f.write(ri.content)
    j = j+1

 

下面学习一下如何获取所有页当中的内容,这里先说下具体思路,对于分页来说,一般情况下它的每一页的链接都是有规律的,你可以根据得出他的页数然后进行循环获取所有的链接,但是这样太麻烦了,。。。想起来我第一次完成test时候什么都不会就是这样做的,真的蠢。另一种方法是,每一个页面如果它有下一页的话,都会有下一页的链接,我们可以根据标签获取到下一页的链接,相当于每一页就是获取了该页的文章链接以及它下一页的链接,可以使用字典进行存储,之后将获取的下一页链接再作为参数继续获取下一页的内容,注意最后一页是没有下一页的,所以这里要进行异常处理,捕捉异常并将下一页链接设置为空,这样子只需要循环获取每一页的内容直到下一页链接为空就可以了。

贴下代码供自己以后参考

# 获取苏轼的所有诗词
baseUrl = "http://www.shicimingju.com"
url = 'http://www.shicimingju.com/chaxun/zuozhe/9.html'
# 定义获取一页之中所有诗词链接和下一页对应的链接
def get_One_Page(url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36 LBBROWSER'
    }
    r = requests.get(url)
    soup = BeautifulSoup(r.text.encode(r.encoding).decode(), 'html.parser')
    # 筛选出www-shadow-card www-main-container下的h3标题并获取其中的链接
    div = soup.find('div', class_='www-shadow-card www-main-container')
    list = [i.find('a').attrs['href'] for i in div.findAll('h3')]
    hrefs = [baseUrl + i for i in list]

    # 获取下一页的链接
    try:
        # 找到相应的div下的text为下一页的标签a的href
        nextUrlDiv = soup.find('div', class_='pagination www-shadow-card')
        nextUrl = baseUrl + nextUrlDiv.find(re.compile(''), text='下一页').attrs['href']
    except Exception as e:
        print('最后一页了。。。')
        nextUrl = ''
    ans = {
        'hrefs': hrefs,
        'nextUrl': nextUrl
    }
    return ans

def write_To_Text(url,i):
    r = requests.get(url)
    soup = BeautifulSoup(r.text.encode(r.encoding).decode(), 'html.parser')
    content = soup.find('div', class_='shici-content').text
    txtDir = os.getcwd() + '\\%s.txt' % i
    with open(txtDir, 'w') as f:
        f.write(content)

ans = get_One_Page(url)
allHrefs = ans['hrefs']
# 循环获取所有的链接,直至下一页不存在
while ans['nextUrl'] != '':
    ans = get_One_Page(ans['nextUrl'])
    allHrefs.extend(ans['hrefs'])
os.chdir('C:\\learn\\python\\爬虫基础学习')
for i in range(1, 100):
    write_To_Text(allHrefs[i], i)

 

 

 

  

posted @ 2019-03-24 20:59  _Ennio  阅读(319)  评论(0编辑  收藏  举报