零基础:21天搞定Python爬虫视屏学习笔记

       昨天,刷知乎。我大概明白为何我总有那么多的迷茫。也明白为何我那么讨厌别人讲人生是一个过程,明白为何同学对讲我:“幸福不是得到你想要的,而是享受你所拥有的”。你努力,会不自觉的提高自己的预期,你努力,就越想得到及时的良好的刺激(有助于激励你的信息反馈),但总在舒适区之外待着的你,意志力是短期内会用完的精神能量,还要面对那些期望落差,以及没有那么多的正能量信息反馈的自我孤独,所以我会有那么多的迷茫,那么多的怀疑,所以,对于努力这件事,不能太用力的努力,我现在所要做的是把短期的过度努力变成长期的恰到好处的喜欢和投入。或许,那些迷茫就会离我而去吧,我想。

                                                                                                                                  -----------与Z信里讲到的话     2019. 8.28

第二章,网络请求

一些函数

#网络请求
from urllib import request
#url解析分割编码
from urllib import parse
#获取网页源码,读取
resp = request.urlopen("http://www.baidu.com")
print(resp.read())
#下载网页信息.,图片
request.urlretrieve('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1566922204525&di=339e9c960befadd84bbc2f2069ebdfd6&imgtype=0&src=http%3A%2F%2Fn1.itc.cn%2Fimg8%2Fwb%2Frecom%2F2016%2F02%2F05%2F145464426598286455.JPEG'
                   ,'深海泰坦.png')
#urlencode 将字典数据转化为url编码顺序
param = {"name":"张山","age":18}
result = parse.urlencode(param)
print(result)

#parse_qs函数的用法,对url字符串进行解码
params = {'name':'张三', 'age':18, 'greet':'hello world'}
qs = parse.urlencode(params)
print(qs)
print(parse.parse_qs(qs))
#urlparse和urlsplit 对url进行分割。urlsplit没有params.一般不用。
url = 'http://www.baidu.com/s;hello?wd=dfdgdfgdfgd&user=dfgfdj&n=df#1'
result = parse.urlparse(url)
result = parse.urlsplit(url)
print(result)
print('sheme:',result.scheme)
print('netloc:', result.netloc)
#request.Request类。在请求首部中增加请求头,User-Agent = http客户端程序信息
url = 'https://www.csdn.net/'
resp = request.urlopen(url)
headers = { 'User-Agent':"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36"}
 data = {
    'first':'true',
     'pn':1,
 }
resp = request.Request(url, headers=headers)
resp = request.urlopen(resp)
print(resp.read())
#ProxyHandler处理器
#IP地址被禁的机制,使用代理服务器,通过代理转发请求。

#没有使用代理
url = "https://www.baidu.com"
resp = request.urlopen(url)
print(resp.read())
#使用代理
print('使用代理的方式!!')
#使用一个ProxyHandler传入一个handler
handler = request.ProxyHandler({'http':"163.204.244.166:9999"})
#使用上面的创建的handle构建一个opener
opener  = request.build_opener(handler)
# 使用opener去发送一个请求
resp = opener.open(url)
print(resp.read())

ProxyHandler处理器(处理):

  1. 代理的原理:在请求目的服务器之前,先请求代理服务器,然后让代理服务器去请求目的服务器。
  2. 代理服务器拿到目的网站的数据后,在转发给我们的代码。
  3. http://httpbin.orp:这个网站可以方便的查看http请求信息
  4. 在代码中使用代理
    1. 使用urllib.request.ProxyHandlerchua()传入一个代理,代理一般为字典
    2. 字典的key依赖于代理服务器能够接受的类型,一般为http、https,值为”ip:port
    3. 使用上一步创建的hendler已及request.build_opener创建一个opener
    4.  使用上一步创建的opener,调用open函数发起请求。

Cookie的使用:

NAME cookie的名字
VALUE cookie的值
Expires cookie的过期时间
Path cookie作用的路径
Domain cookie作用的域名
SECUER 是否只在https协议下起作用

cookie的基本模块:

  • CookieJar基本类:管理HTTP cookie的值,存储http请求生成的Cookie,向传入的http请求添加cookie的对象,整个Cookie都存储在内存中。
  • FileCookieJar:将cookie 信息存储到文件里。Filename是存储Cookie的文件名。delayload为Ture时延迟访问文件。
  • MozillaCookieJar:创建与火狐浏览器Cookie.txt兼容的FileCookie实例。
  • LwPCookieJar:从FileCookieJar派生而来,创建Set-Cookie文件

使用Cookie登录

#使用cookie实现登录
from urllib import request
from http.cookiejar import CookieJar
from  urllib import parse
#不使用Cookie去请求主页
liruilong_url = "http://www.renren.com/441992574/profile"
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36'
    ,"Cookie":"anonymid=jzuwr9qvhzckya; depovince=GW; _r01_=1; JSESSIONID=abck6aHRYaKfhbTelbxZw; ick_login=933914fc-d2dc-4ad9-bc04-984b44895554; jebe_key=e592ad6f-ac4f-4c45-b82d-bd993b4700fb%7C98c73539fee1cffb5f9cc1945695ee9a%7C1566975619199%7C1%7C1566975619913; wp_fold=0; jebecookies=ce08c92d-fd6b-423b-a48a-3c3b5135e94f|||||; _de=A4BF4EA119AD552CA61D7350ED501D1C6DEBB8C2103DE356; p=59e59693e5f9e9e207fbea357eb1229c4; ap=441992574; first_login_flag=1; [email protected]; ln_hurl=http://hdn.xnimg.cn/photos/hdn421/20130209/1700/h_main_Ty4X_277a00000280111a.jpg; t=8c790067f935cd2df3f28ffc41d798934; societyguester=8c790067f935cd2df3f28ffc41d798934; id=441992574; xnsid=28f8b7e9; ver=7.0; loginfrom=null; jebe_key=e592ad6f-ac4f-4c45-b82d-bd993b4700fb%7C3290e3689bd6952d3672b3892c4aa0ca%7C1566976101710%7C1%7C1566976102421"
}
req = request.Request(url=liruilong_url, headers=headers)
resp = request.urlopen(req)
#print(resp.read().decode('utf-8'))
with open('renre.html','w', encoding='utf-8') as fp:
    #wtite函数必须写入一个Str的数据类型
    #resp.read()读出来是一个byte类型的数据。
    #byes - > decode -> str
    #str - > encode -> bytes
    fp.write(resp.read().decode('utf-8'))

自动化登录

#导入模块
from urllib import request
from http.cookiejar import CookieJar
from urllib import parse


headers = {
            'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36'
        }

def get_opener():
    #登录
    #1,创建一个Cookiejar对象
    cookiejar = CookieJar();
    #2,使用CookieJar创建一个HttpCookieProcess对象
    handler = request.HTTPCookieProcessor(cookiejar)
    #3,使用上一步创建的handler创建一个opener
    opener = request.build_opener(handler)
    return opener

#4,使用opener发送登录的请求(用户名和密码)
def log_renren(opener):

    data = {
        "email":"[email protected]",
        "password":"liruilong,1008"
           }
    login_url = "http://www.renren.com/PLogin.do"
    req = request.Request(login_url, data= parse.urlencode(data).encode('utf-8'),headers=headers)
    opener.open(req)

def visit_profile(opener):
    #5,访问个人主页
    liruilong_url = "http://www.renren.com/441992574/profile"
    #获取个人主页的时候不要新建一个opener,要使用之前的那一个
    #因为之前哪一个已经包含登录所需要的Cookie信息
    req = request.Request(liruilong_url, headers =headers)
    resp = opener.open(req)
    with open("renren.html", 'w', encoding='utf-8') as fp:
        fp.write(resp.read().decode('utf-8'))

if __name__ == '__main__':
    opener = get_opener()
    log_renren(opener)
    visit_profile(opener)

保存Cookie到本地:

可以使用cookiejar的save方法。并且保存到本地。

#encoding utf-8

from urllib import request
from http.cookiejar import MozillaCookieJar
#该位置指定了文件名,,save就不需要指定了,反之
cookiejar = MozillaCookieJar('cookie.txt')
cookiejar.load(ignore_discard=True)
handler = request.HTTPCookieProcessor(cookiejar)
opener = request.build_opener(handler)
resp = opener.open('https://blog.csdn.net/sanhewuyang/article/list/1?')
#保存Cookie信息
cookiejar.save()
cookiejar.save(ignore_discard=True)

for cookie in cookiejar:
    print(cookie)

request库:

一,发送GET请求,

#encoding :utf-8
import  requests
reponse = requests.get("https://www.baidu.com")
print(type(reponse.text))
#自己猜测的解码方式
print(reponse.text)
print(type(reponse.content))
print(reponse.content)
#指定解码方式
print(reponse.content.decode('utf-8'))
#返回当前请求的url
print(reponse.url)
#字符编码
print(reponse.encoding)
#状态码
print(reponse.status_code)

二,添加header和查询参数:

如果想要添加headers,可以传入hanfers参数来增加请求头中的请求首部。

  • 发送get请求,直接rquests.get(url)方法实现
  • requests的一些属性,requests.content是直接从网络上抓取数据,没有进过解码,所以是一个bytes类型。
  • rquests.text;与context类似,requests会根据自己的猜测进行解码,乱码的时候一般使用requests.content.decode('utf-8)
  • 发送post请求,requests.post(url),传入data数据,不需要编码,可以直接传递。
  • 入如果返回的是json数据,那么可以调用 response.json方法。
  • 
    import requests
    
    
    
    headers = {
        #告知服务器请求的原始资源的URI
    'Referer':'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput='
        #HTTP客户端程序信息,伪装成客户端请求
    ,'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36'
    }
    date = {
        'first':'true'
        #页数
        ,'pn':'1'
        #关键字
        ,'kd':'python'
    }
    reponse = requests.post("https://www.lagou.com/jobs/positionAjax.json?city=%E5%8C%97%E4%BA%AC&needAddtionalResult=false",\
    #传输 的数据和首部字段
    data=date,headers=headers)
    print(reponse.json())
    print(reponse.text)
    

    三,使用代理:

  • 使用requests添加代理,只要在请求的方法传递proxies参数就可以了。
  • import requests
    
    proxy = {
        'http':'115.211.43.6:9000'
    }
    #使用代理
    response = requests.get("http://www.baidu.com",proxies=proxy)
    print(response.text)
    requests处理Cookie信息
  • import requests
    
    #获取当前请求的Cookie
    pesponse = requests.get("https://www.baidu.com")
    print(pesponse.cookies.get_dict())
    #session
    

    处理cookie:

  • 如果想要在多次请求中处理Cookie,那么应该使用session,

  • import requests
    
    data = {
            "email":"[email protected]",
            "password":"liruilong,1008"
            }
    headers = {
                'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36'
            }
    
    login_url = "http://www.renren.com/PLogin.do"
    #创建一个session对象
    session = requests.session()
    #由session对象发出post请求把Cookie信息传递过去
    session.post(login_url, data=data, headers=headers)
    #由session对象发出get请求获取登录后的页面信息。
    response = session.get("http://www.renren.com/441992574/profile")
    
    with open('renrens.html', 'w', encoding='utf-8') as fp:
        fp.write(response.text)

    处理不信任的ssl证书,

  • import requests
    #处理不信任的ssl证书
    rept = requests.get('https://www.12306.cn/index/',verify=False)
    print(rept.content.decode('utf-8'))

     

第三章,数据分析

xPath语法:

  • nodename:选取次节点的所有子节点,
  • / 选取根节点下的元素,选择某节点下的某个元素,
  • //  :   //div  从全局节点中选择节点,随便找那个位置
  • @ :  //div[@id]    选取某个节点的属性
  • 谓词:
  • //body/div[1]  获取body的第一个元素, [<3],[last()]倒数第二个元素,
  • [@name]拥有指定属性的元素,
  • [@name ='12']选取所有属性等于123的name元素。
  • [@class,'''sw']:模糊匹配,选取Class文件中sw字段的属性
  • //body[*]  :div下的所有元素
  • contains:有时候某个元素包含多个值,那么可以使用‘contains’函数,//div[contains(@class,'job_detail')]
  • 下标是从零开始的,不是从一开始的。

lxml库:

  • 是一个html、xml解析器,用来解析和获取html/xml.
  • 使用html类去解析html文档。以字符串的方式:使用etree.HTML()
    text = """ html文本"""
    htmlelement = etree.HTML(text)
    #打印html,使用html类去解析html文档。
    print(etree.tostring(htmlelement, encoding='utf-8').decode('utf-8'))
    

     

  • 从文件中读取html代码:
    # 从文件中解析
    def para():
        # 有可能解析不成功,指定解析器
        parser = etree.HTMLParser(encoding='utf-8')
        htmlelement = etree.parse("baidu.html", parser=parser)
        print(etree.tostring(htmlelement, encoding='utf-8').decode('utf-8'))
    

     

  • 从lxml中使用XPath语法:
    from lxml import etree
    
    # 构造解析器
    paeser = etree.HTMLPullParser(encoding="utf-8")
    html = etree.parse("renre.html",parser=paeser)
    # 获取指定的所有标签。
    # xpath函数的返回的是列表
    trs = html.xpath("//link")
    for link in trs:
        print(etree.tostring(link, encoding='utf-8').decode('utf-8'))
    
    #获取指定索引的指定标签
    link = html.xpath('//link[2]')[0]
    print(etree.tostring(link, encoding='utf-8').decode('utf-8'))
    
    #获取所有指定属性的所有标签
  • lis = html.xpath("//li[@class='fd-nav-item']") for link in lis: print(etree.tostring(link, encoding='utf-8').decode('utf-8')) # 获取所有a标签中的href属性值 #因为是获取值。 atag = html.xpath("//a[@href]") atag = html.xpath('//a/@href') for link in atag: print(link) #获取所有的文本信息 trs = html.xpath("//div[position()>1]") for tr in trs: # 在当前标签下获取子孙标签,用xpath函数, #因该在// 之前加 点,代表当前元素下获取。 ul = tr.xpath(".//ul/@class") # 获取li的所有文本 title= tr.xpath('.//li/text()') print(title) break
  •  

  •  

 

 

 

你可能感兴趣的:(python学习)