python - 如何从网页中抓取 href?
问题描述
我正在尝试抓取指向产品页面的网址。
我 webscape 的页面如下。 https://groceries.morrisons.com/browse/fruit-veg-176738
但是,我的代码只对我想获取的部分信息(每个产品页面的 url)进行了 webscape。我想修复代码以获取产品页面的所有 url。你能帮忙解决这个问题吗?
这是我的代码:
# import required libraries
from bs4 import BeautifulSoup
import requests
# obtain page urls in meat and fish category
url='https://groceries.morrisons.com/browse/fruit-veg-176738'
# get source code from website using 'requests' library
source=requests.get(url).text
# create a BeautifulSoup object
soup=BeautifulSoup(source, 'lxml')
# find the source code of item list.
list_source=soup.find('div', class_='main-column')
# identify the location of urls of each item page
url_source=list_source.find('div', class_='fop-contentWrapper')
# get the urls
url_tail=url_source.a.attrs['href']
# full website address
url='https://groceries.morrisons.com/'+url_tail
url_list=[]
# grab all the urls using for loop
for url_source in list_source.find_all('div', class_='fop-contentWrapper'):
url_tail=url_source.a.attrs['href']
url='https://groceries.morrisons.com/'+url_tail
url_list.append(url)
上面代码的结果只抓取了 67 个 URL。
len(url_list)
67
但是,预期的结果是抓取 439 个 URL。
len(url_list)
439
解决方案
问题可能出在页面的加载中。据我了解,它只获取页面的“可见”部分,因为向下滚动时会加载更多项目。要通过请求抓取整个页面,您必须监控页面网络活动(F12 - Chrome 中的网络)以查看向下滚动时页面执行的请求。下面是我在Selenium中的解决方案来抓取整页。它每 2 秒向下滚动一次页面到页面末尾以加载此页面中的每个项目,然后使用bs4进行解析。
In [69]: from bs4 import BeautifulSoup
...: from selenium import webdriver
...: import time
...: driver = webdriver.Chrome()
...: driver.get('https://groceries.morrisons.com/browse/fruit-veg-176738?display=500')
...:
...: #Scrolling the page every 2 second to the end of the page
...: last_height = driver.execute_script("return document.body.scrollHeight")
...: h=0
...: while h<last_height:
...: h += 450
...: time.sleep(2)
...: driver.execute_script(f"window.scrollTo(0, {h});")
...:
...: print('\r', "Wait... Parsing", int(h/last_height*100), "%" , end='')
...:
...: html = driver.page_source
...: soup=BeautifulSoup(html, 'lxml')
...: list_source=soup.find('div', class_='main-column')
...: url_source=list_source.find('div', class_='fop-contentWrapper')
...: url_tail=url_source.a.attrs['href']
...: url='https://groceries.morrisons.com/'+url_tail
...: url_list=[]
...: len(list_source.find_all('div', class_='fop-contentWrapper'))
Wait... Parsing 100 %
这是结果:
Out[69]: 439
请纠正我,如果我错了。
推荐阅读
- javascript - 如何在 mapbox-gl-js 的单层中使用多行?
- python - 使用链接数据路径访问使用 python 抓取的链接
- faunadb - 如果文档存在则更新,否则在区区数据库中创建一个新文档
- xcode - 在版本 12.2 beta 4 中,当我在新应用程序中创建一个简单标签时,它在几秒钟后不可见
- c# - Asp.net Core MVC - 数据检索问题
- kotlin - Kotlin forEach 带有标签的返回不起作用
- javascript - 如何读取文件内容并将文件存储在目录中?
- amazon-web-services - AWS 弹性推理错误:
正在编译,因为它是从调用 - typescript - 打字稿:如何使用未知字符串键迭代对象
- java - 更新用户的 Jhipster 问题