这种网页怎么爬取网页图片

Selenium+R爬取动态网页
问题的提出
做过爬虫的同学都知道,一个网站的数据通常并不会集中于一个页面,而是通过好多页面来呈现,这就涉及到一个获取“下一页”的问题,一般来讲,点击网站的“下一页”,网页的URL就会发生变化,以豆瓣高分电影为例:&
这种情况下,每一页的URL之间是有规律可循的, 我曾经从网上爬取豆瓣电影评分的网站就类似这种很容易操作。
但是,如果页面中包含js代码,特别是点击“下一页”之后网页URL不变,这种情况就很令人头疼了。比如像今天我要爬取对的网页,大家先感受下:
下面我们就尝试爬取这一网站中所有文章的URL,网站链接为:
在R当中操作selenium以我目前的掌握有两个包,分别是RSelenium和seleniumPipes两个包,前者可能由于本人不能上谷歌,同时火狐浏览器又没有装到C:盘下,所以难以配置成功,有兴趣的同学可以研究一下解决对策,这里我使用了seleniumPipes这个包进行操作,在完成本文操作之前,你最好保证:
你的计算机配置了java环境
你的计算机已经安装了selenium-server-standalone
你安装了火狐浏览器(其他浏览器亦可,配置方法大同小异)
接下来,你需要启动selenium服务,这个稍后在R代码中展示。
#启动selenium服务,命令中的路径就是对应selenium的路径
system("java -jar \"E:/Drivers/Selenium/selenium-server-standalone-2.53.1.jar\"",wait = FALSE)
#加载包,激活驱动
library(seleniumPipes)
## Warning: package 'seleniumPipes' was built under R version 3.3.3
## Loading required package: httr
## Loading required package: jsonlite
## Warning: package 'jsonlite' was built under R version 3.3.1
## Loading required package: xml2
## Loading required package: magrittr
## Loading required package: whisker
#这里我设置了服务的重试次数,因为在代码执行过程中我发现重试基本没用,所以将默认的3次调成1次以节省时间
options("seleniumPipes_no_try" = 1)
#这里给出了了火狐浏览器的安装路径
firefox_path &- "E:/Program Files (x86)/Mozilla Firefox/firefox.exe"
#启动selenium远程服务
remDr &- remoteDr(remoteServerAddr = "http://127.0.0.1:4444/wd/hub", browserName = "firefox", path = "", extraCapabilities = list("firefox_binary"= firefox_path),newSession = TRUE)
#打开太原规划网:http://www.tygh.gov.cn/tygh/tygh/list.action?channelId=246#,点击下一页,没有问题。
url &- "http://www.tygh.gov.cn/tygh/tygh/list.action?channelId=246#"
remDr_sess &- remDr%&%go(url)%&%setTimeout(type = "script",15000)
执行上述代码你会发现你的计算机弹出一个火狐浏览器,然后登陆了太原规划网。函数remoteDr的remoteServerAddr参数一般使用上述代码中的即可,或者可以通过开启selenium服务(上面代码块的第一个语句,或者在cmd中输入java
E:/Drivers/Selenium/selenium-server-standalone-2.53.1.jar返回的信息中包含该信息,如下图:
remoteDr的另外一个需要注意的参数是extraCapabilities,实际上这个参数制定了用户安装浏览器的位置,而RSelenium中我么有发现类似功能:(。完成上述工作后,就可以开心的用程序模拟人工操作点击“下一页”了。
#下面尝试对每一页进行爬取,然后点击下一页继续
#首先得到总页数
pagesAll &- remDr_sess%&%findElement("xpath","//span[@class = \"pgTotalPage\"]")%&%getElementText()%&%as.numeric()
#准备存放文件URL的容器
herfs &- list()
titles &- list()
for (i in 1:pagesAll){
print(paste(i, currPage, sep = "-"))
#爬取数据。
lis &- remDr_sess%&%findElements("xpath","//li/a")
titles_temp &- lapply(lis, function(x) x%&%getElementText())#OK
herfs_temp &- lapply(lis, function(x) x%&%getElementAttribute("href"))#OK
print("Titles-Herfs")
print(paste(length(titles_temp),length(herfs_temp),sep = "-"))
titles &- c(titles,titles_temp)
herfs &- c(herfs,herfs_temp)
#前往下一页
#Sys.sleep(8)
if(i != pagesAll){
remDr_sess%&%findElement("link text", "下一页")%&%elementClick()
print("Done!")
我想,大多数同学运行上面代码会报错,这里就不贴图了,原因很简单:点击“下一页”之后页面并没有及时刷新,直接获取元素值当然会报错,期初,我是通过添加Sys.sleep(10)来让程序等待页面刷新之后进行下一步操作,但是这样看起来有点低端,而且,并不是万无一失之策,上策是要确认页面已经是刷新了的,同时确认是我们希望的那一页,改进后的代码如下:
pagesAll &- remDr_sess%&%findElement("xpath","//span[@class = \"pgTotalPage\"]")%&%getElementText()%&%as.numeric()
#准备存放文件URL的容器
herfs &- list()
titles &- list()
for (i in 1:pagesAll){
Stime = 1 #设定初始睡眠时间
print(paste(i,"of", pagesAll))
currPage &- 0 #设定当前页初始值
#判断是否页面已经刷新
wCount &- 0 #初始化一个计数器,用来确认尝试次数和确定系统睡眠时间
while(i & currPage){
wCount &- wCount + 1
currPage &- try(remDr_sess%&%findElement("id","curPage")%&%getElementAttribute("value")%&%as.numeric(),silent = TRUE)#获取当前页码
#如果不是首次尝试,睡眠一段时间
if(wCount & 1){
Sys.sleep(Stime + wCount)
#如果发生报错,等待一段时间,跳出该次循环,继续下一次while循环
if(inherits(currPage,"try-error")){
print("Error")
Sys.sleep(Stime + wCount)
#显示当前页码是否是正确的页码
print(paste(i, currPage, sep = "-"))
#至此,确认网页已经更新到相应网页,可以开始爬取数据。
lis &- remDr_sess%&%findElements("xpath","//li/a")
titles_temp &- lapply(lis, function(x) x%&%getElementText())#OK
herfs_temp &- lapply(lis, function(x) x%&%getElementAttribute("href"))#OK
print("Titles-Herfs")
print(paste(length(titles_temp),length(herfs_temp),sep = "-"))
titles &- c(titles,titles_temp)
herfs &- c(herfs,herfs_temp)
#前往下一页
if(i != pagesAll){
remDr_sess%&%findElement("link text", "下一页")%&%elementClick()
print("Done!")
到此,我们就将这个网站上所有的文章标题和链接弄下来了,selenium功不可没,有了它,同学们爬取数据的时候更是得心应手。
PS:老实说,之前写代码从来没用过while,甚至怀疑它有必要吗?看来真是——存在即合理!
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。相关词典网站:怎么爬取动态生成的网页? - CNode技术社区
东莞 · 广东 · 小前端
比如京东的商品列表页,列表中的价格和评论都是通过jsonp获取,再渲染出来的。而用 nodecrawler 只能爬取最原始的页面,请问如何才能等页面的js执行完毕后才返回html?
先谢谢各位大佬的提议。
phantomjs模拟请求,不过速度很慢.如果对速度有要求的话比如可以对京东抓包,找出接口,然后再用正则匹配来截取jsonp里想要的数据
有接口,但是有很多个,一页所有商品需要访问3个接口各3次。
自豪地采用
这就要看你想要的数据是啥了,原理都一样
这不是更好吗?页面都不用爬了,直接调取它接口
可是不爬没有sku 的ID。
自豪地采用
nightmare 都可以
一般来说,常见的就是容器和找接口。
不过如果对稳定性没有太高的要求,其实还有一个方案,直接控制台或者暴力猴,通过jquery 和 cors 把数据提交给服务器。
既然有接口,直接调接口拿数据就好了呀
这个问题无数的人已经总结无数次。请
用scrapy+selenium,很轻松
用谷歌network 可以看到接口url,直接爬接口 然后整理数据就行
puppeteer 不解释
puppeteer:
我不管你是不是动态页面,只要你是web,撸起袖子就是干
我的天,这么简单
这个肯定不行的。。。。因为要实时爬取。
如果京东的接口有这么简单就可以破的话,我就不用来发帖啦。
百度的结果,基本都是要不Python(可是我不会),要不就是phantomjs(太慢了,因为有几十个页面,每个页面又有几十个请求)
有jsonp的url但是还是需要先爬取需要的sku的id。
这个 puppeteer 的速度如何?能不能在几分钟内爬完100个页面?
能说下思路吗?谢谢。
我爬携程酒店就是这样的,虽然麻烦 但是你爬了id什么的之后 建立自己的数据库 接下来只要爬就行了。
方向1 headless类
工具:puppeteer(推荐), phantomjs(基本已经不会再更新)
场景:如果对抓取不熟悉,或者页面js做了太多事情,接口响应和你最终要的东西相差很多时。
优点:省心,前端开发熟悉的套路。headless类的帮你模拟出浏览器的加载过程,你自己拿渲染生成好的数据就可以了。
缺点:可定制化低-& 易被防抓; 性能差
方向2 抓接口
工具:你熟悉语言的httpRequest库
场景:熟悉抓取,你能分析出你要的数据来自那些接口以及接口的前后逻辑;性能要求高
优点:可定制化高,请求你想发成啥样都可以;性能好
缺点:对开发者分析能力和动手能力要求高
至于性能相差多少,可以理解成进程级别和请求级别,这要看具体抓取目标环境和你的具体实现了。
如果楼主还是一脸懵的话,建议你甭管用啥,先run起来,渐渐就有感觉了
那你是先爬完所有的id再去更新各个id的数据还是爬一些更新一些这样呢?
好的,感谢这么详细的解答。我试试两种的效率。
把所有静态的数据拿到之后
puppeteer 只是一个 headless 的 chromium 浏览器而已,Google 官方出来的,所以之前的 phantomjs,casperjs,nightmare 就结束了历史使命了。
抓取速度只看你网速,反正一般爬虫你都是搞集群的,所以 puppeteer 的启动速度可以忽略不计(比起其他几个,它的启动速度已经是最快的了)。
还是要看你的具体业务场景,简单的那种还是直接 curl 快,需要执行 js 的,非 puppeteer 莫属。
我只是个业余的,集群什么的都不懂。现在正在研究puppeteer 但是扔上服务器后(阿里的装不上chromium,扔的国外)动不动就30s超时。醉了。
说明你的服务器跟你要抓取的网站之间的访问速度太慢了…
好吧,确实是这样的。用阿里云就基本维持在1s左右一个页面。
我是这样安装chromium的 ,设置一个 。。。skip。。。= true 的参数来跳过chromium安装,然后手动安装chromium
const browser = await puppeteer.launch({
executablePath : 'C://Users/33318/AppData/Local/Chromium/Application/chrome.exe',
指定chromium的绝对地址
好的,我也是这么做的。然后在我国外的服务器,只需2s就下载好了。。。。万恶的高墙。
自豪地采用
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
服务器赞助商为
,存储赞助商为
,由提供应用性能服务。
新手搭建 Node.js 服务器,推荐使用无需备案的手把手教大家爬取js动态生成的页面 - FreeBuf专栏·玩转Python爬虫
手把手教大家爬取js动态生成的页面
首发专栏:关注
玩过爬虫的人都遇到过这种网页,标签内的内容是js生成的,也就是说在源网页不存在,用选择器当然也获取不到东西,那怎么办呢?本文将手把手教大家写一个自动化脚本,相信学习本文后大家都会爬取js生成的页面
我们以为例,任意进入一个详情界面,如图:
经过我的分析红框处的数字是js自动生成的,我们先验证一下首先按f12进入调试页面
如图这个数字呈现在我们眼前,你可能会有这样的疑问,这这个数字不是能获取到吗,小编是不是在耍我,别急,大家继续往后看,我们用程序验证一下
import urllib.requesturl = "http://www.eshow365.com/zhanhui/html/.html"data = urllib.request.urlopen(url).read()data = data.decode('UTF-8')print(data)
我们把网页打印了一遍,找到位置,会看到这样一个情况数字竟然没有啦!!!这该怎么办呢???
下面我们开始对这个页面进行深入爬取,让大家获取到这个数字
首先大家要下载以下插件
这是一个用于web应用程测试的工具
pip install selenium
是一种无界面的浏览器,用于完成网页的渲染,大家可以具体学习,毕竟这个也是门有研究价值的一个技术
http://phantomjs.org/download.html
解压就可以用
打卡解压后的文件,找到bin下的phantomjs.exe将这个路径放到PATH路径下
工具准备完成,下面上代码咯
from selenium import webdriverurl = "http://www.eshow365.com/zhanhui/html/.html"driver = webdriver.PhantomJS(executable_path='E:/phantomjs/bin/phantomjs.exe')//这个路径就是你添加到PATH的路径driver.get(url)print (driver.page_source)
运行之后出现如图所示
数字爬下来了,是不是很简单呀
用phantomjs有的时候很麻烦,如果可以抓到json,反而更简单。
必须您当前尚未登录。
必须(保密)
可以给我们打个分吗?java 求Js网页如何爬取 - ITeye问答
http://www.yanglee.com/product/product_Lists.aspx?ptype=
js网站的爬取,我一般就是看页面上请求后台数据 的地址,然后获取JSON数据,
但就是这个网页,怎么爬,获取后台请求的JSON都获取不到啊
问题补充:生成的数据在页面源码里,所以用上面的网址 第一页能获取到,但是 翻页,改参数什么的就不行了 啊
js 发送的 是ajax
翻页访问的请求地址
http://www.yanglee.com/ajax/ProductSearch.ashx?_=6&mode=Search&perpage=60&page=1&ProStr=NodeCode%253D%20and%2520FlowState%253D99%2520and%2520IsDel%253D0%2520and%2520ProductLevel%253C%253E%2527VIP%&strOrder=released%2520desc&ProductState=&jigou=&qixian=&shouyi=&InvestField=&ApplyWay=
如果 用程序调 可能还需要加这些个Header 参数吧
Referer http://www.yanglee.com/product/product_Lists.aspx?ptype=
perpage=60&page=1 每页记录数 当前页面值
你翻页和修改数据是怎么请求后台的,并且你的前台页面是怎么处理你返回来的数据的
已解决问题
未解决问题

我要回帖

更多关于 网页爬取 的文章

 

随机推荐