python做个爬虫


0.前言


本文或许用到以下工具:

  • requests
  • re
  • 面向对象
  • pyqt5
  • pyinstaller

暂时爬取网站: https://huaban.com/favorite/beauty

1.探究过程


1.1 第一个难题:

关于爬到的html与f12得到的有区别,所以re写pattern不能凭着F12
目标:找到一个合适的pattern便于找到url

所谓查看网页源代码,就是别人服务器发送到浏览器的原封不动的代码。这是爬虫获得的代码
你那些在源码中找不到的代码(元素),那是在浏览器执行js动态生成的,这些能在审查元素中看到
通过审查元素就,,,,看到就是浏览器处理过的最终的html代码。

然后试了试更换头信息,

就离谱,requests.get过来的基本没找到<div>标签,F12检查元素全是<div>标签
感觉:爬到的和F12到的是两个东西

1.2 第二个难题:

从得到的text中找出图片的地址

先用 http://www.bejson.com/ 进行text分析,发现图片的地址为
https://hbimg.huabanimg.com/+key

1.3 第三个难题:

关于得到数据的不完整性,
目标:找出url_next

爬到的东西只有前面一些图片,经查询好像是一种关于动态网页异步更新的技术
参考: https://zhuanlan.zhihu.com/p/27346009
(当然网站表面没有页,表面的url也没有变)

经查询,向下翻页时XHR会多出请求,url地址已给出
是时候更改1.0版本的代码,让它找到更多的图片🎈

经过第一个问题的折磨,容易理解:

  • 虽然(翻页后的)url,用浏览器无法访问,但get可以爬到

2.基础知识


2.1 关于requests

开始使用第一步:

  import requests
  r=requests.get("http://")
  r.status_code                     #en,返回200表示成功

开始使用第二步:

  r.encoding = 'utf-8'
  r.text                            #en,返回网站的html

其它:

r.apparent_encoding 【从内容分析出响应内容编码方式,返回一个编码方式字符串】
r.raise_for_status 【如果不是200,返回异常码】

七个主要方法:

  • requests.request(method,url,**kwargs)
  • requests.get(url,**kwargs), headers中伪装头信息
  • requests.post()
  • requests.put()
  • requests.patch()
  • requests.head()
  • requests.delete()

2.2 关于re

https://www.unielu.com/posts/10df.html

2.3 关于面向对象

if __name__ == '__main__'
表示:只有当该文件作为一个独立的脚本运行时才会被调用。
换句话说,如果在其它文件中导入此文件,那么条件中的语句不被执行。

3.代码实现


1.0版本代码:

import re
import requests
import os

pwd="C:/temp/temp"
url = "https://huaban.com/favorite/beauty/" #这是你要爬取的页面url
url_img = "https://hbimg.huabanimg.com/" #这是它放图片的url前缀
num=0

#伪装头信息
head = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36 Edg/84.0.522.49'}

def download(file,url):
    print("开始下载:",file,url)
    try:
        r = requests.get(url,stream=True)
        with open(file, 'wb') as fd:
            for chunk in r.iter_content():
                fd.write(chunk)
    except Exception as e:
        print("下载失败了",e)

def main(url):
    global num
    print("*******************************************")
    print("你的请求网址是:",url)

    r=requests.get(url,headers=head)
    pattern=re.compile('{"pin_id":(\d*?),.*?"key":"(.*?)",.*?"like_count":(\d*?),.*?"repin_count":(\d*?),.*?}',re.S)
    pid=0
    items=re.findall(pattern,r.text)

    for item in items:
        pid,key,like_cnt,repin_cnt=item
        print("开始下载第{}张图片".format(num))

        pic_url=url_img+key    #图片的url地址
        filename=pwd+str(pid)+".jpg"  #文件保存的名字

        if os.path.isfile(filename):
            print("文件存在:",filename)
            continue

        download(filename,pic_url)
        num+=1

if not os.path.exists(pwd):
    os.makedirs(pwd)
main(url)

1.1版本代码:

import re
import requests
import os

pwd="C:/temp/temp"
url = "http://huaban.com/favorite/beauty/"
url_img = "https://hbimg.huabanimg.com/"
url_next="https://huaban.com/favorite/beauty?kdbpp4xg&max="
num=0

#伪装头信息
head = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36 Edg/84.0.522.49'}

def download(file,url):
    print("开始下载:",file,url)
    try:
        r = requests.get(url,stream=True)
        with open(file, 'wb') as fd:
            for chunk in r.iter_content():
                fd.write(chunk)
    except Exception as e:
        print("下载失败了",e)

def main(url):
    global num
    print("*******************************************")
    print("你的请求网址是:",url)

    r=requests.get(url,headers=head)
    pattern=re.compile('{"pin_id":(\d*?),.*?"key":"(.*?)",.*?"like_count":(\d*?),.*?"repin_count":(\d*?),.*?}',re.S)
    pid=0
    items=re.findall(pattern,r.text)

    for item in items:
        pid,key,like_cnt,repin_cnt=item
        print("开始下载第{}张图片".format(num))

        pic_url=url_img+key    #图片的url地址
        filename=pwd+str(pid)+".jpg"  #文件保存的名字

        if os.path.isfile(filename):
            print("文件存在:",filename)
            continue

        download(filename,pic_url)
        num+=1
    main(url_next+pid+"&limit=100&wfl=1")    #比1.0多出的地方,参考问题3

if not os.path.exists(pwd):
    os.makedirs(pwd)
main(url)

4.小结


2020.8.1
啦啦啦, 1.1版本成功,激动ing
今天还试了试beautifulsoup,fiddler,没领悟~


文章作者: ╯晓~
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 ╯晓~ !
评论
  目录