Elle.com搜索结果加载更多按钮爬取方法及重复数据问题解决
问题根因与解决思路
核心问题原因
你代码出现大量重复条目主要由三个问题共同导致:
- 未添加请求头标识,Elle的反爬策略会将无User-Agent的请求判定为爬虫,固定返回第一页搜索结果,所以你遍历page=1到page=9拿到的都是第一页的内容
- 内层循环触发
counter ==100的break后,仅终止了当前页的条目遍历,外层分页循环还会继续执行,重复抓取内容 - 没有对抓取到的文章链接做去重校验,同一文章出现在多页结果时会被重复入库
具体实现思路
- 先给所有requests请求添加浏览器User-Agent请求头,伪装成正常用户访问,避免反爬返回固定页面
- 新增去重校验逻辑,每次拿到新的文章链接先判断是否已经在urls列表中,存在就直接跳过
- 调整终止逻辑,触发100条上限时直接终止外层分页循环,同时新增分页有效性校验,当连续2页内容一致时说明已经到最后一页,提前终止爬取
- 新增请求间隔,避免请求频率过高被封IP
修正后可运行代码
import requests, nltk, pandas as pd, time from bs4 import BeautifulSoup as bs # 配置请求头,伪装成Chrome浏览器访问 HEADERS = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36' } def get_hits(url): # 给详情页请求也加请求头 r = requests.get(url, headers=HEADERS) soup = bs(r.content, 'html.parser') body = [] for p in soup.find_all('p',{'class':'body-text'}): sentences = nltk.sent_tokenize(p.text) result1 = [s for s in sentences if 'kim' in s.lower()] if result1: body.extend(result1) result2 = [s for s in sentences if 'kanye' in s.lower()] if result2: body.extend(result2) return body if body else ["no hits"] titles =[] key_hits = [] urls = [] counter = 1 max_count = 100 # 记录上一页第一条链接,判断翻页是否生效 last_first_link = None for i in range(1,10): # 请求间隔1秒,避免被封 time.sleep(1) url = f'https://www.elle.com/search/?page={i}&q=kanye' r = requests.get(url, headers=HEADERS) soup = bs(r.content, 'html.parser') groups = soup.find_all('div',{'class':'simple-item grid-simple-item'}) # 分页有效性校验 if not groups: break current_first_link = 'https://www.elle.com' + groups[0].find('a')['href'] if current_first_link == last_first_link: # 翻页后内容和上一页一致,说明已经到最后一页 break last_first_link = current_first_link for j in range(len(groups)): article_url = 'https://www.elle.com' + groups[j].find('a')['href'] # 去重校验 if article_url in urls: continue article_title = groups[j].find('div',{'class':'simple-item-title item-title'}).text urls.append(article_url) titles.append(article_title) key_hits.append(get_hits(article_url)) if counter == max_count: break counter += 1 if counter == max_count: break data = pd.DataFrame({ 'Title':titles, 'Body':key_hits, 'Links':urls }) print(data.head())
营销研究员需要了解的爬虫基础知识点
- 反爬合规常识:商业网站普遍会限制爬虫访问,常规的伪装措施包括添加User-Agent请求头、控制请求频率(每秒1-2次请求),爬取前可查看目标网站
/robots.txt路径的爬取规则,商业用途的抓取要注意规避合规风险 - 数据去重准则:做内容分析类的抓取时,优先使用内容的唯一标识(比如本文的文章链接)做去重,不要依赖标题或者计数判断,避免同一内容出现在多个搜索分页、重名内容等场景导致的重复数据
- 结果校验习惯:每次批量抓取后先抽样校验数据一致性,比如比对前几页的抓取结果是否和浏览器看到的一致,避免反爬返回无效内容做了无用功
- 关键词匹配优化:做文本关键词匹配时建议统一转为大小写后再判断,避免因为首字母大写、全大写等格式问题漏掉匹配结果
内容的提问来源于stack exchange,提问作者Dee Cap
相关产品推荐
相关产品推荐

