def getNewsDetail(self, url): resp = self.request(url, 'GET', {}) if not resp: print('请求数据失败,请检查你的网络环境') return '' html = etree.HTML(resp) title = ''.join(html.xpath('//div[@class="content-article"]/h1/text()')).strip() content = '\n'.join(html.xpath('//div[@id="ArticleContent"]/p[@class="one-p"]/text()')).strip() return title, content
时间: 2024-02-06 20:02:05 浏览: 56
这段代码是该类的一个方法,用于获取新闻的标题和内容,参数url表示新闻的URL地址。方法内部首先使用request方法向指定的URL发送GET请求,获取新闻的HTML页面。如果请求失败,则在控制台输出错误信息并返回空字符串。如果请求成功,则使用lxml库中的etree模块解析HTML页面,获取新闻的标题和内容。其中,title使用xpath表达式获取class属性为"content-article"的div元素下的h1元素的文本内容,并使用join和strip方法将文本内容转换为字符串并去除前后空格;content则使用xpath表达式获取id属性为"ArticleContent"的div元素下的class属性为"one-p"的p元素的文本内容,并使用join和strip方法将文本内容转换为字符串并去除前后空格。最后,将获取到的标题和内容作为元组的形式返回。
相关问题
def request(self, url, method, data, retry=5): resp = None while retry: retry = retry - 1 try: if method == 'GET': resp = self._sess.get(url=url, params=data, headers=self._headers, timeout=5) # 发送Get请求 elif method == 'POST': resp = self._sess.post(url=url, json=data, headers=self._headers, timeout=5) # 发送Post请求 else: raise ValueError('method参数有误') if resp.status_code == 200 and resp.content: # 若得到正常请求,则返回请求体信息 resp.encoding = 'utf-8' return resp.text except Exception as e: print('请求 {} 失败,正在尝试重新请求...'.format(url)) print(e) time.sleep(3 + random.randint(1, 10) * 0.1) # 延迟一定秒数,爬取太快容易请求失败 return ''
这段代码是该类的一个方法,用于向指定的URL发送HTTP请求,参数url表示请求的URL地址,参数method表示请求的方法(GET或POST),参数data表示请求的参数,参数retry表示请求失败后的重试次数(默认为5)。方法内部使用requests模块中的Session对象(即self._sess)发送HTTP请求,根据method参数的不同,使用get或post方法发送请求。其中,headers参数使用了上文提到的_user_agent属性作为请求头部信息。如果请求成功(状态码为200),则将响应体中的文本数据作为函数返回值。如果请求失败,则会在控制台输出错误信息,并在3秒到4秒之间的随机时间之后进行重试,最多重试retry次。如果所有重试都失败,则返回空字符串。
import requests from bs4 import BeautifulSoup import openpyxl class LianJiaSpider(): def __init__(self): self.url = 'https://bj.lianjia.com/ershoufang/pg{0}/' self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.0.12022 SLBChan/109'} def send_request(self, url): resp = requests.get(url, headers=self.headers) if resp.status_code == 200: return resp def parse_html(self, resp): lst = [] html = resp.text bs = BeautifulSoup(html, 'lxml') ul = bs.find('ul', class_='sellListContent') li_list = ul.find_all('li') for item in li_list: title = item.find('div', class_='title').text positionInfo = item.find('div', class_='positionInfo').text address = item.find('div', class_='address').text followInfo = item.find('div', class_='followInfo').text tag = item.find('div', class_='tag').text totalPrice = item.find('div', class_='totalPrice totalPrice2').text unitPrice = item.find('div', class_='unitPrice').text # print(unitPrice) lst.append((title, positionInfo, address, followInfo, tag, totalPrice, unitPrice)) print(lst) self.save(lst) def save(self, lst): wb = openpyxl.Workbook() sheet = wb.active for row in lst: sheet.append(row) continue wb.save('D:/爬虫/链家.csv') def start(self): for i in range(1, 5): full_url = self.url.format(i) resp = self.send_request(full_url) #print(resp.text) self.parse_html(resp) if __name__ == '__main__': lianjia = LianJiaSpider() lianjia.start()使用以上代码爬取数据保存到文件中只显示最后一页30条数据,前面页码的数据都被覆盖了,如何更改
在 `save` 方法中,每次循环都重新创建了一个新的 `Workbook` 对象,因此在保存数据时会覆盖之前的数据。您可以将 `Workbook` 对象的创建放在 `__init__` 方法中,这样每次保存数据时都可以使用同一个 `Workbook` 对象。另外,您还可以将文件名中的页码部分替换为变量 `i`,这样每次保存的文件都会有不同的文件名,不会被覆盖。修改后的代码如下:
```python
import requests
from bs4 import BeautifulSoup
import openpyxl
class LianJiaSpider():
def __init__(self):
self.url = 'https://bj.lianjia.com/ershoufang/pg{0}/'
self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.0.12022 SLBChan/109'}
self.wb = openpyxl.Workbook()
self.sheet = self.wb.active
self.sheet.append(('标题', '位置', '地址', '关注信息', '标签', '总价', '单价'))
def send_request(self, url):
resp = requests.get(url, headers=self.headers)
if resp.status_code == 200:
return resp
def parse_html(self, resp):
html = resp.text
bs = BeautifulSoup(html, 'lxml')
ul = bs.find('ul', class_='sellListContent')
li_list = ul.find_all('li')
for item in li_list:
title = item.find('div', class_='title').text
positionInfo = item.find('div', class_='positionInfo').text
address = item.find('div', class_='address').text
followInfo = item.find('div', class_='followInfo').text
tag = item.find('div', class_='tag').text
totalPrice = item.find('div', class_='totalPrice totalPrice2').text
unitPrice = item.find('div', class_='unitPrice').text
self.sheet.append((title, positionInfo, address, followInfo, tag, totalPrice, unitPrice))
print('第{}页数据爬取完成'.format(i))
def save(self):
self.wb.save('D:/爬虫/链家_{}.csv'.format(i))
def start(self):
for i in range(1, 5):
full_url = self.url.format(i)
resp = self.send_request(full_url)
self.parse_html(resp)
self.save()
if __name__ == '__main__':
lianjia = LianJiaSpider()
lianjia.start()
```
在修改后的代码中,我将文件名改为了 `"D:/爬虫/链家_{}.csv".format(i)`,这样每次保存的文件名都会包含页码,不会被覆盖。同时,我将保存数据的操作从 `parse_html` 方法中分离出来,放在了单独的 `save` 方法中,并且在 `__init__` 方法中创建了 `Workbook` 对象和表头。这样就可以避免每次循环都重新创建一个新的 `Workbook` 对象,从而避免了数据被覆盖的问题。
阅读全文