【发布时间】:2017-11-29 17:00:54
【问题描述】:
我一直在玩网络抓取(使用 Python 3.6.2 进行这个练习),我觉得我有点失去它了。给定this 示例链接,这就是我想要做的:
首先,如您所见,页面上有多个类别。单击上面的每个类别都会给我其他类别,然后是其他类别,依此类推,直到我到达产品页面。所以我必须深入 x 次。我认为递归会帮助我实现这一点,但在某处我做错了。
代码:
在这里,我将解释我解决问题的方式。首先,我创建了一个会话和一个简单的通用函数,它将返回一个 lxml.html.HtmlElement 对象:
from lxml import html
from requests import Session
HEADERS = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/62.0.3202.94 Safari/537.36"
}
TEST_LINK = 'https://www.richelieu.com/us/en/category/custom-made-cabinet-doors-and-drawers/1000128'
session_ = Session()
def get_page(url):
page = session_.get(url, headers=HEADERS).text
return html.fromstring(page)
然后,我想我还需要另外两个函数:
- 一个获取类别链接
- 另一个获取产品链接
为了区分一个和另一个,我发现只有在类别页面上,每次都有一个包含CATEGORIES的标题,所以我使用了:
def read_categories(page):
categs = []
try:
if 'CATEGORIES' in page.xpath('//div[@class="boxData"][2]/h2')[0].text.strip():
for a in page.xpath('//*[@id="carouselSegment2b"]//li//a'):
categs.append(a.attrib["href"])
return categs
else:
return None
except Exception:
return None
def read_products(page):
return [
a_tag.attrib["href"]
for a_tag in page.xpath("//ul[@id='prodResult']/li//div[@class='imgWrapper']/a")
]
现在,唯一剩下的就是递归部分,我确定我做错了什么:
def read_all_categories(page):
cat = read_categories(page)
if not cat:
yield read_products(page)
else:
yield from read_all_categories(page)
def main():
main_page = get_page(TEST_LINK)
for links in read_all_categories(main_page):
print(links)
所有代码放在一起:
from lxml import html
from requests import Session
HEADERS = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/62.0.3202.94 Safari/537.36"
}
TEST_LINK = 'https://www.richelieu.com/us/en/category/custom-made-cabinet-doors-and-drawers/1000128'
session_ = Session()
def get_page(url):
page = session_.get(url, headers=HEADERS).text
return html.fromstring(page)
def read_categories(page):
categs = []
try:
if 'CATEGORIES' in page.xpath('//div[@class="boxData"][2]/h2')[0].text.strip():
for a in page.xpath('//*[@id="carouselSegment2b"]//li//a'):
categs.append(a.attrib["href"])
return categs
else:
return None
except Exception:
return None
def read_products(page):
return [
a_tag.attrib["href"]
for a_tag in page.xpath("//ul[@id='prodResult']/li//div[@class='imgWrapper']/a")
]
def read_all_categories(page):
cat = read_categories(page)
if not cat:
yield read_products(page)
else:
yield from read_all_categories(page)
def main():
main_page = get_page(TEST_LINK)
for links in read_all_categories(main_page):
print(links)
if __name__ == '__main__':
main()
有人可以为我指出关于递归函数的正确方向吗?
【问题讨论】:
-
我建议使用
scrapy进行网络爬取,特别是针对您的问题,我会使用CrawlSpider,您只需定义项目页面的结构,并使用正则表达式来查找和关注类别. -
我知道。但在进入 Scrapy 之前,我想先了解一下基础知识 :)
-
@eLRuLL 做
print(page.xpath('//div[@class="boxData"][2]/h2')[0].text.strip())确实返回了我的期望。 (我编辑了第一个代码,因为我错过了索引)
标签: python python-3.x xpath web-scraping lxml