爬虫学习总结

痛定思痛。 2022-11-11 06:00 369阅读 0赞

啦啦啦,滴滴答,我是卖报的小行家,今天终于完成长达两天的python爬虫的学习了
在这里插入图片描述

今天的总结呢,包括以下几点:

一.关于基础知识的归类

爬取基本过程

1.选着要爬的网址 (url)

2.使用 python 登录上这个网址 (urlopen等)

3.读取网页信息 (read() 出来)

4.将读取的信息放入 BeautifulSoup

5.选取 需要的tag 信息等

登录网站的方式

  • urlopen:

    from urllib.request import urlopen

    if has Chinese, apply decode()

    html = urlopen(

    1. "https://mofanpy.com/static/scraping/basic-structure.html"

    ).read().decode(‘utf-8’)
    print(html)

  • request:
    1)get:

    import requests
    import webbrowser
    param = { “wd”: “莫烦Python”} # 搜索的信息

    它会将我们搜索的关键词以及wd:和前面固定格式组成一个url

    r = requests.get(‘http://www.baidu.com/s‘, params=param)
    print(r.url)

    打开链接

    webbrowser.open(r.url)

2)post:

  1. 登录
  2. #要投入的信息
  3. data = { 'firstname': '莫烦', 'lastname': '周'}
  4. #要投入的链接requesturl而不是当前网页链接
  5. r = requests.post('http://pythonscraping.com/files/processing.php', data=data)
  6. print(r.text)
  • driver

    from selenium import webdriver

    driver = webdriver.Chrome() # 打开 Chrome 浏览器

    将刚刚复制的帖在这

    driver.get(“https://mofanpy.com/“)
    driver.find_element_by_xpath(u”//img[@alt=’强化学习 (Reinforcement Learning)’]”).click()
    driver.find_element_by_link_text(“About”).click()
    driver.find_element_by_link_text(u”赞助”).click()
    driver.find_element_by_link_text(u”教程 ▾”).click()
    driver.find_element_by_link_text(u”数据处理 ▾”).click()
    driver.find_element_by_link_text(u”网页爬虫”).click()

    得到网页 html内容

    html = driver.page_source # get html

    ,还能网页截图

    driver.get_screenshot_as_file(“./img/sreenshot1.png”)
    driver.close()

这种方式使用selenium模拟对浏览器的操作,其中模拟对浏览器的操作是通过安装火狐浏览器中一个叫Katalon Recorder插件实现自动生成代码的。

解析网页的方式

  • BS4
    输出内容

    from bs4 import BeautifulSoup
    from urllib.request import urlopen

    if has Chinese, apply decode()

    html = urlopen(“https://mofanpy.com/static/scraping/basic-structure.html").read().decode('utf-8‘)
    print(html)
    soup = BeautifulSoup(html, features=’lxml’)
    print(soup.h1)
    print(‘\n’, soup.p)
    爬虫教程
    all_href = soup.find_all(‘a’)
    print(all_href)
    for l in all_href]:

    1. print(l.["href"])

    print(‘\n’, all_href)

按class匹配信息

  1. soup = BeautifulSoup(html, features='lxml')
  2. # use class to narrow search
  3. month = soup.find_all('li', { "class": "month"})
  4. for m in month:
  5. #获得所收集到的列表中所夹的文本信息
  6. print(m)
  7. print(m.get_text())

结合正则

  1. soup = BeautifulSoup(html, features='lxml')
  2. #找soup里所有img标签,他的属性用正则来匹配
  3. img_links = soup.find_all("img", { "src": re.compile('.*?\.jpg')})
  4. for link in img_links:
  5. print(link['src'])
  • 正则表达式

    import re
    from urllib.request import urlopen

    if has Chinese, apply decode()

    html = urlopen(

    1. "https://mofanpy.com/static/scraping/basic-structure.html"

    ).read().decode(‘utf-8’)
    print(html)
    res = re.findall(r”(.+?)“, html)
    print(“\nPage title is: “, res[0])
    res = re.findall(r”

    (.*?)

    “, html, flags=re.DOTALL) # re.DOTALL if multi line
    print(“\nPage paragraph is: “, res[0])

    Page title is: Scraping tutorial 1 | 莫烦Python

    res = re.findall(r”

    (.*?)

    “, html, flags=re.DOTALL) # re.DOTALL if multi line
    print(“\nPage paragraph is: “, res[0])

    Page paragraph is:

    这是一个在 莫烦Python

    爬虫教程 中的简单测试.

    res = re.findall(r’href=”(.*?)”‘, html)
    print(“\nAll links: “, res)

    All links:

    [‘https://mofanpy.com/static/img/description/tab_icon.png‘,
    ‘https://mofanpy.com/‘,
    ‘https://mofanpy.com/tutorials/scraping‘]

加速爬虫的方式

  • 多进程
  • 异步

特殊功能

  • session
    同样是执行上面的登录操作, 下面就是使用 session 的版本. 创建完一个 session 过后, 我们直接只用 session 来 post 和 get. 而且这次 get 的时候, 我们并没有传入 cookies. 但是实际上 session 内部就已经有了之前的 cookies 了.

    session = requests.Session()
    payload = { ‘username’: ‘Morvan’, ‘password’: ‘password’}
    r = session.post(‘http://pythonscraping.com/pages/cookies/welcome.php‘, data=payload)
    print(r.cookies.get_dict())

    { ‘username’: ‘Morvan’, ‘loggedin’: ‘1’}

  1. r = session.get("http://pythonscraping.com/pages/cookies/profile.php")
  2. print(r.text)
  3. # Hey Morvan! Looks like you're still logged into the site!
  • 下载
    1)urlretrieve

    from urllib.request import urlretrieve
    urlretrieve(IMAGE_URL, ‘./img/image1.png’)

2)request
正常下载

  1. import requests
  2. #将网址内容下载存在r中
  3. r = requests.get(IMAGE_URL)
  4. with open('./img/image2.png', 'wb') as f:
  5. #将r中的内容写入到文件中
  6. f.write(r.content)

批量下载

  1. r = requests.get(IMAGE_URL, stream=True) # stream loading
  2. with open('./img/image3.png', 'wb') as f:
  3. for chunk in
  4. r.iter_content(chunk_size=32):
  5. f.write(chunk)

二.环境配置

1.request:pip3 install requests
2.beautifulsoup4:pip3 install beautifulsoup4
3.4.pip3 install selenium

三.实践过程的心酸历程(爬取百度图片)

爬取位置:https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1616152719672\_R&pv=&ic=&nc=1&z=&hd=&latest=&copyright=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&sid=&word=%E8%9F%AA%E8%9B%84/

直接使用别人代码

  1. from bs4 import BeautifulSoup
  2. import requests
  3. URL = "http://www.nationalgeographic.com.cn/animals/"
  4. html = requests.get(URL).text
  5. soup = BeautifulSoup(html, 'lxml')
  6. div_ul = soup.find_all('div', { "class": "imgpage"})
  7. # print(div_ul)
  8. print(len(div_ul))
  9. for ul in div_ul:
  10. imgs = ul.find_all('li', { "class": "imgitem"})
  11. # print(imgs)
  12. print(len(imgs))
  13. print(12345)
  14. for img in imgs:
  15. url = img['data-thumburl']
  16. r = requests.get(url, stream=True)
  17. image_name = url.split('/')[-1]
  18. with open('./img/%s' % image_name, 'wb') as f:
  19. for chunk in r.iter_content(chunk_size=128):
  20. f.write(chunk)
  21. print('Saved %s' % image_name)

并将网站和对应匹配方式改成自己观察网页的结果,但是存在以下两个问题:
1.lxml未安装
网址
在这里插入图片描述
在这里插入图片描述
2.无论如何匹配我在网页中观察到特定类的标签都返回空列表无法匹配,我刚开始以为是我的标签或者对应类的类型书写有误,检查一大顿也没有问题,最后我想输出一下我访问的网页看看到底和我看的网页是不是一个网页,要是一样的话可真就见了鬼了,于是我用下列代码测试:

  1. import requests
  2. import webbrowser
  3. #它会将我们搜索的关键词以及wd:和前面固定格式组成一个url
  4. r = requests.get('https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1616152719672_R&pv=&ic=&nc=1&z=&hd=&latest=&copyright=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&sid=&word=%E8%9F%AA%E8%9B%84/')
  5. print(r.text())
  6. print(r.url)
  7. #打开链接
  8. webbrowser.open(r.url)

运行结果
在这里插入图片描述

https://wappass.baidu.com/static/captcha/tuxing.html?&ak=c27bbc89afca0463650ac9bde68ebe06&backurl=https%3A%2F%2Fwww.baidu.com%2Fs%3Fwd%3Dpython&logid=9429735157699859545&signature=ab2baa7ec785cf123cfa8f498a9a0664&timestamp=1580387558
在这里插入图片描述
解决:
在网上搜了各种绕开百度验证或者破解安全验证的方法,但是有的太复杂,有得不好用,但是有意无意我发现了为什么机器登录会产生验证而 正常人为登录为什么不出现验证码:
我们在使用浏览器正常登录百度指数网站的时候发现一般不会弹出验证码的提示。但是如果你使用无头浏览器去登录的时候就会出现验证码,那么这两者登录的区别在哪里呢?
经过我不断的验证发现了两个问题,当我们使用无头浏览器登录的时候做一些类似于人类的操作,例如在窗口中滑动鼠标,或者改变窗口的大小,这样百度指数网站就会认为你是人为的在操作。
第二个问题就是在我们使用无头浏览器输入账号和密码的时候,我们在手动输入密码的时候或多或少的在输入字符之间都会存在时间间隔,而使用无头浏览器的时候程序会零间隔的输入,这样百度指数网站就会认为你是一个程序在输入了。

所以我想到了一个办法只要浏览器认为不是人打开的浏览器就可以正常访问而不需要进行验证,正好因为 Selenium 需要操控你的浏览器,它能控制你的浏览器, 有模有样地学人类看网页.他就是基于这个浏览器程序来进行操作的,打开浏览,进行点击,输入密码等操作,所以我选择使用它来进行打开网页并得到网页内容进行爬取

使用Selenium

  1. from selenium import webdriver
  2. from bs4 import BeautifulSoup
  3. import requests
  4. import time
  5. driver = webdriver.Chrome() # 打开 Chrome 浏览器
  6. # 将刚刚复制的帖在这
  7. driver.get("https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1616152719672_R&pv=&ic=&nc=1&z=&hd=&latest=&copyright=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&sid=&word=%E8%9F%AA%E8%9B%84/")
  8. # 得到网页 html内容
  9. html = driver.page_source # get html
  10. # print(html)
  11. print(2)
  12. soup = BeautifulSoup(html, 'lxml')
  13. div_ul = soup.find_all('div', { "class": "imgpage"})
  14. # print(div_ul)
  15. print(len(div_ul))
  16. for ul in div_ul:
  17. imgs = ul.find_all('li', { "class": "imgitem"})
  18. # print(imgs)
  19. print(len(imgs))
  20. print(12345)
  21. for img in imgs:
  22. url = img['data-thumburl']
  23. r = requests.get(url, stream=True)
  24. image_name = url.split('/')[-1]
  25. with open('./image/%s' % image_name, 'wb') as f:
  26. for chunk in r.iter_content(chunk_size=128):
  27. f.write(chunk)
  28. print('Saved %s' % image_name)
  29. #,还能网页截图
  30. driver.get_screenshot_as_file("./image/sreenshot1.png")

这样就可以完美避过验证但是也存在三个问题:
1.需要下载驱动才能使selenium控制浏览器
报错:Selenium: Runtime.executionContextCreated has invalid ‘context’:
1)首先在查看你查看自己chrome浏览器的版本
在这里插入图片描述
2.下载对应版本的驱动
下载网址
我的版本是89.0.4389.23/
在这里插入图片描述
点进去,虽然是win64但是win32仍然好用
在这里插入图片描述
注:一定要下载对应版本的驱动否则会报错如下,别问我咋知道的,因为我也刚爬出坑,哈哈
WebDriverException: Message: unknown error: Runtime.executionContextCreated has invalid ‘context’
3.解压缩文件,并将driver.exe文件放在chrome.exe文件的同级目录中
我的电脑是:C:\Users\123\AppData\Local\Google\Chrome\Application
在这里插入图片描述
4.将刚才所放文件位置的路径添加系统环境路径Path中
在这里插入图片描述
在这里插入图片描述
5.如果是使用anaconda环境的话,重启命令行,重新加载路径,报错消失

2.如何编写对网页操作的selenium代码
1.下载火狐浏览器
下载网址、
2.安装插件Katalon Recorder
也可以直接在火狐中搜索插件并直接安装,安装后要进行激活和注册
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3.插件的使用,如果安装完成会在下图位置处显示
在这里插入图片描述
4.实现记录
在这里插入图片描述
5.导出代码
在这里插入图片描述

在这里插入图片描述
3.如何爬取网页所有的内容
第三个问题就是我看到有很多类型imgpage的div里面img类型的li标签中存的是图片并可以通过其中data-thumburl属性获得网址并下载,而我们反复实验就只能下载20张图片,我们只能下载第一个类型imgpage的div里面img类型的li标签中存的图片,别imgpage的div里面无法匹配的到,自然也就无法下载,我突然发现有的时候我只能找到一个类型imgpage的div,也就是我能下载的那些图片所在div,而有些时候我可以查看到所有该类型的div在这里插入图片描述
后来我发现原来你刚打开网页的时候只会显示并加载第一页的图片,也就只能加载一个div内容,而随着你下拉滑块查看网页所有内容,此时div才会逐渐添加到中,这是用jsp写的动作,只有你向下拉动滚动条才会在中添加网页之前未显示的内容,网页的源代码不断更新,是网页的一种行为,所以我们要打开网页之后读取网页内容之前不断下拉滑块,显示网页所有内容是网页源代码中包含网页所有内容。

解决:
转载于:https://www.zhihu.com/question/46528604?sort=created
定义一个函数,实现将滚轮滑到页面最下方的功能,这个在官方文档中有(为了让页面载入完整,每5秒下移一次,一共下移10次)

  1. def execute_times(times):
  2. for i in range(times + 1):
  3. driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
  4. time.sleep(5)
  5. execute_times(10)

4.我的代码和结果

  1. from selenium import webdriver
  2. from bs4 import BeautifulSoup
  3. import requests
  4. import time
  5. driver = webdriver.Chrome() # 打开 Chrome 浏览器
  6. # 将刚刚复制的帖在这
  7. driver.get("https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1616152719672_R&pv=&ic=&nc=1&z=&hd=&latest=&copyright=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&sid=&word=%E8%9F%AA%E8%9B%84/")
  8. print(1)
  9. def execute_times(times):
  10. for i in range(times + 1):
  11. driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
  12. time.sleep(5)
  13. execute_times(10)
  14. # 得到网页 html内容
  15. html = driver.page_source # get html
  16. # print(html)
  17. print(2)
  18. soup = BeautifulSoup(html, 'lxml')
  19. div_ul = soup.find_all('div', { "class": "imgpage"})
  20. # print(div_ul)
  21. print(len(div_ul))
  22. for ul in div_ul:
  23. imgs = ul.find_all('li', { "class": "imgitem"})
  24. # print(imgs)
  25. print(len(imgs))
  26. print(12345)
  27. for img in imgs:
  28. url = img['data-thumburl']
  29. r = requests.get(url, stream=True)
  30. image_name = url.split('/')[-1]
  31. with open('./image/%s' % image_name, 'wb') as f:
  32. for chunk in r.iter_content(chunk_size=128):
  33. f.write(chunk)
  34. print('Saved %s' % image_name)
  35. #,还能网页截图
  36. driver.get_screenshot_as_file("./image/sreenshot1.png")

发表评论

表情:
评论列表 (有 0 条评论,369人围观)

还没有评论,来说两句吧...

相关阅读

    相关 爬虫总结

    爬虫代码编写时需要注意一些各项: 1、重试下载 5xx错误发生时,需要考虑重试下载,重试几次也可以自定义 400错误发生时,也有可能需要考虑重试 2、控制爬虫的深

    相关 爬虫学习总结

    啦啦啦,滴滴答,我是卖报的小行家,今天终于完成长达两天的python爬虫的学习了 ![在这里插入图片描述][20210319192931466.jpg_pic_center