【极客学院】-python学习笔记

编程入门 行业动态 更新时间:2024-10-11 09:20:54

【极客学院】-python<a href=https://www.elefans.com/category/jswz/34/1770117.html style=学习笔记"/>

【极客学院】-python学习笔记

极客学院课程地址:.html?ss=1


向网页提交数据:


get,post 交互方式

分析目标网站

表单提交功能


get:从服务器获得数据

post:向服务器传数据


eg:


request.post

步骤:构造表单,提交,获取返回信息


异步加载:菜做好一道上一道

不同于 菜做好了,再一次性上齐


网页 → 审查  → Headers  →  Request Method:GET (页面并没有 more,这里也没有POST)

Form Data → page:2


当有多个 page 的时候,直接提取,可能因为异步加载,无法提取到 more 的信息

这时 可以建立一个字典,并用 request.post 去提交表单,提取数据

#-*-coding:utf8-*-
import requests
import reurl='/'data = {'entities_only':'true'<span style="background-color: rgb(153, 255, 153);">,</span>'page':'1'
}html_post = requests.post(url<span style="background-color: rgb(153, 255, 153);">,</span>data=data)
title = re.findall('"card-title">(.*?)</div>', html_post.text, re.S)for each in title:print (each)


继续

实战:

/

前20页的 课程名称,课程介绍,课程时间,课程等级,学习人数


步骤:

requests获取网页

re.sub换页

正则表达式匹配内容


问题:

课程介绍,后面是省略号 的情况该怎么办?

爬虫只能爬到可以看到的

有的课程的课程介绍也可能为空


解决方案:

先抓大后抓小:


另:windows下将命令提示符的编码强制转化成utf-8

import  sys
reload(sys)
sys.setdefaultencoding("utf-8")



实践中遇到问题:

按课程中的代码敲出来后,会有一些错误


比如运行后,info.txt 中没有内容:

因为:网页的元素不是课程里的那样了,所以需要修改匹配的线索,这样修改了 everyclass,title 和 content,


<li id="2430" test="0" deg="0" >


但是到 timeandlevel 又有错误了

TypeError: '_sre.SRE_Match' object is not subscriptable

说明:

“XXX”object is not subscriptable
说的是XXX对象不是可索引的,可索引的对象有list,tuple等
如果你确定你的XXX是一个可迭代对象的话,可以尝试用list()函数把它转化为列表,然后通过索引读取元素


尝试分部找规律,提出 time 和 level,

info['classtime'] = re.search('"time-icon"></i><em>(.*?)</em>',eachclass,re.S).group(1)
info['classlevel'] = re.search('"xinhao-<span style="color:#ff0000;">icon</span>"></i><em>(.*?)</em>',eachclass,re.S).group(1)

但是 有的 level 的 icon 后面可能会加数字,导致,查找出的结果会有none

<i class="xinhao-icon2"></i><em>中级</em>



后来发现问题在于,把 re.findall 写成了 re.search

timeandlevel = re.search('<em>(.*?)</em>',eachclass,re.S)


所以,只查找了一个 em,没办法分配哦

<_sre.SRE_Match object; span=(1122, 1146), match='<em>3课时\n\t\t\t\t\t\t\t57分钟</em>'>


而实际上是这样的数据
<dd class="mar-b8"><i class="time-icon"></i><em>4课时
<span style="white-space:pre">	</span>56分钟</em>
</dd>
<dd class="zhongji"><span style="white-space:pre">	</span><i class="xinhao-icon"></i><em>初级</em>
</dd>


最终代码:

#-*-coding:utf8-*-import requests
import re#url = '/'#html = requests.get(url)#print(html.text)#content = re.findall('', html.text, re.S)class spider(object):def __init__(self):print (u'开始爬取内容...')def changepage(self,url,total_page):page_group = []                 #获得需要爬取的所有 page 的列表now_page = int(re.search('pageNum=(\d+)', url, re.S).group(1))for i in range(now_page,total_page+1):link = re.sub('pageNum=\d+','pageNum=%s'%i,url, re.S)page_group.append(link)return page_groupdef getsource(self,url):html = requests.get(url)        #获取网页源代码return html.textdef geteveryclass(self,source):#everyclass = re.findall('(<li deg="".*?</li>)',source,re.S )        #先把所有课程找出来everyclass = re.findall('(<li id=.*?</li>)',source,re.S )return everyclassdef getinfo(self,eachclass):info = {}                       #定义字典# info['title'] = re.search('target="_blank">(.*?)</a>',eachclass,re.S).group(1)info['title'] = re.search('title="(.*?)" alt',eachclass,re.S).group(1)# info['content'] = re.search('</h2><p>(.*?)</p>',eachclass,re.S).group(1)info['content'] = re.search('none;">(.*?)</p>',eachclass,re.S).group(1)#timeandlevel = re.search('<em>(.*?)</em>',eachclass,re.S)timeandlevel = re.<span style="background-color: rgb(153, 255, 153);">findall</span>('<em>(.*?)</em>',eachclass,re.S)info['classtime'] = timeandlevel[0]info['classlevel'] = timeandlevel[1]# info['classtime'] = re.search('"time-icon"></i><em>(.*?)</em>',eachclass,re.S).group(1)# info['classlevel'] = re.search('"xinhao-icon"></i><em>(.*?)</em>',eachclass,re.S).group(1)info['learnnum'] = re.search('"learn-number">(.*?)</em>',eachclass,re.S).group(1)return infodef saveinfo(self,classinfo):f = open('info.txt','a')            #打开 info.txt, 使用追加的方式for each in classinfo:f.writelines('title:' + each['title'] + '\n')f.writelines('content:' + each['content'] + '\n')f.writelines('classtime:' + each['classtime'] + '\n')f.writelines('classlevel:' + each['classlevel'] + '\n')f.writelines('learnnum:' + each['learnnum'] + '\n\n')f.close()#程序入口if __name__ == '__main__':          #如果程序是自己使用 .py 文件运行classinfo = []                  #定义一个列表用来存课程信息url = '/?pageNum=1'jikespider = spider()           #实例化 类all_links = jikespider.changepage(url,2)for link in all_links:print(u'正在处理页面: '+ link)html = jikespider.getsource(link)everyclass = jikespider.geteveryclass(html)for each in everyclass:info = jikespider.getinfo(each)classinfo.append(info)jikespider.saveinfo(classinfo)


知识点:

参考:

Python中re(正则表达式)模块学习  .html


[1]re.search

  re.search函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回,如果字符串没有匹配,则返回None。

re.search的函数原型为: re.search(pattern, string, flags)

每个参数的含意与re.match一样。 

re.match与re.search的区别:

re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。

now_page = int(re.search('pageNum=(\d+)', url, re.S).group(1))


python group()

参考:.html

正则表达式中,group()用来提出分组截获的字符串,()用来分组

例:

import re
a = "123abc456"
print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0)   #123abc456,返回整体
print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1)   #123
print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2)   #abc
print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3)   #456

re.search('pageNum=(\d+)', url, re.S)    <span style="white-space:pre">		</span>#<_sre.SRE_Match object; span=(35, 44), match='pageNum=1'>
re.search('pageNum=(\d+)', url, re.S).group(1)<span style="white-space:pre">		</span># 1

re.match

  re.match 尝试从字符串的开始匹配一个模式,如:下面的例子匹配第一个单词。 

re.match的函数原型为:re.match(pattern, string, flags)

第一个参数是正则表达式,这里为"(\w+)\s",如果匹配成功,则返回一个Match,否则返回一个None;

第二个参数表示要匹配的字符串;

第三个参数是标致位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。


[2]re.sub

  re.sub用于替换字符串中的匹配项。下面一个例子将字符串中的空格 ' ' 替换成 '-' :  

re.sub的函数原型为:re.sub(pattern, repl, string, count)

其中第二个参数是替换后的字符串;本例中为'-'

第四个参数指替换个数。默认为0,表示每个匹配项都替换。

re.sub还允许使用函数对匹配项的替换进行复杂的处理。如:re.sub(r'\s', lambda m: '[' + m.group(0) + ']', text, 0);将字符串中的空格' '替换为'[ ]'。

for i in range(1,3):link = re.sub('pageNum=\d+','pageNum=%s'%i,url, re.S)print(link)
结果:
/?pageNum=1
/?pageNum=2


[3]re.findall

  re.findall可以获取字符串中所有匹配的字符串。如:re.findall(r'\w*oo\w*', text);获取字符串中,包含'oo'的所有单词。


everyclass = re.findall('(<li id=.*?</li>)',source,re.S)

timeandlevel = re.findall('<em>(.*?)</em>',eachclass,re.S)
info['classtime'] = timeandlevel[0]
info['classlevel'] = timeandlevel[1]



更多推荐

【极客学院】-python学习笔记

本文发布于:2024-02-24 16:05:09,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1695874.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:学习笔记   学院   python

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!